Files
probably-rendering-one-more…/apps/studio/src/components/Ref17Cover.tsx
T
codex-bot ce1963f692
studio CI and deployment / verify-and-deploy (pull_request) Successful in 7m29s
Improve fixed-layout copy contrast and correct SVG title hydration
2026-10-28 17:27:28 +08:00

34 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type {Idea,Slide} from '../content/ideas';
type Template=NonNullable<Idea['template']>;
export function Ref17Cover({template,slide,masthead=template.masthead,guides=false}:{template:Template;slide:Slide;masthead?:string[];guides?:boolean}){
const scale=10,W=template.width*scale,H=template.height*scale;
const slot=(id:string)=>{const s=template.slots.find(s=>s.id===id);if(!s)throw Error('Missing source slot '+id);return s.box.map(v=>v*scale)};
const [mx,my,mw,mh]=slot('I01'),[cx,cy,cw,ch]=slot('I02'),[dx,dy,dw,dh]=slot('D02'),[bx,by,bw,bh]=slot('D03'),[lx,ly,lw,lh]=slot('D01');
const [aX,aY,aW,aH]=slot('T01'),[bX,bY,bW,bH]=slot('T02'),[tX,tY,tW,tH]=slot('T03'),[sX,sY,sW,sH]=slot('T04');
const first=masthead[0]||'STUDY',second=masthead[1]||'Skills',body=slide.body.split('\n').slice(0,3);
const font1=Math.min(aH*1.2,aW/Math.max(1,first.length*.72)),font2=Math.min(bH,bW/Math.max(1,second.length*.59));
const titleSize=Math.min(tH*.72,tW/Math.max(1,Array.from(slide.heading).length*1.06));
const bodySize=Math.min(32,...body.map(s=>sW/Math.max(1,Array.from(s).reduce((n,c)=>n+(/[\u3400-\u9fff]/.test(c)?1:.5),0))));
const accent=slide.accent||'#d8ddd4';
return <svg xmlns="http://www.w3.org/2000/svg" viewBox={`0 0 ${W} ${H}`} width={W} height={H} role="img" aria-label={`${slide.label||slide.heading},ref-17 模板封面试版`} data-layout-id={template.id} style={{display:'block',width:'100%',height:'auto'}}>
<title>{(slide.label||slide.heading)+' · 模板试版'}</title><desc>源自 ref-17 的九个固定构件。图片位使用色块,占位文案可替换,暂无具体工具内容。</desc>
<rect width={W} height={H} fill={template.paper}/>
<g data-slot="I01"><rect x={mx} y={my} width={mw} height={mh} fill={slide.color}/></g>
<g data-slot="I02"><ellipse cx={cx+cw/2} cy={cy+ch/2} rx={cw/2} ry={ch/2} fill={accent}/></g>
<g data-slot="D02" fill="none" stroke={template.ink} strokeWidth="2" opacity=".75"><rect x={dx+1} y={dy+9} width={dw-2} height={dh-18} rx={(dh-18)/2}/><path d={`M${dx+19} ${dy+dh/2}H${dx+dw-19}`}/></g>
<g data-slot="D01"><path d={`M${lx} ${ly+lh/2}H${lx+lw}`} stroke={template.ink} strokeWidth="2"/></g>
<g data-slot="D03"><rect x={bx} y={by} width={bw} height={bh} fill={accent}/></g>
<g fill={template.ink} fontFamily="Georgia, 'Times New Roman', serif" fontWeight="400">
<text data-slot="T01" x={aX} y={aY+aH*.9} fontSize={font1} letterSpacing={-font1*.035}>{first}</text>
<text data-slot="T02" x={bX} y={bY+bH*.76} fontSize={font2} letterSpacing={-font2*.045}>{second}</text>
</g>
<text data-slot="T03" x={tX} y={tY+tH*.8} fill={template.ink} fontFamily="'PingFang SC', 'Microsoft YaHei', sans-serif" fontWeight="600" fontSize={titleSize} letterSpacing={-titleSize*.025}>{slide.heading}</text>
<g data-slot="T04" fill={template.ink} fontFamily="Arial, 'PingFang SC', sans-serif">
<text x={sX} y={sY+32} fontSize="22" letterSpacing="2">{slide.kicker||'TEMPLATE / XX'}</text>
{body.map((line,i)=><text key={i} x={sX} y={sY+135+i*58} fontSize={bodySize}>{line}</text>)}
<text x={sX} y={sY+sH-62} fontSize="19" letterSpacing="1">CONTENT</text><text x={sX} y={sY+sH-26} fontSize="19" letterSpacing="1">PLACEHOLDER</text>
</g>
{guides&&<g aria-hidden="true" fontFamily="Arial,sans-serif">{template.slots.map(s=>{const[x,y,w,h]=s.box.map(v=>v*scale),color=({text:'#2c64d8',image:'#d36b30',decoration:'#08875d'} as Record<string,string>)[s.kind]||'#666';return <g key={s.id}><rect x={x} y={y} width={w} height={h} fill={color} fillOpacity=".04" stroke={color} strokeWidth="2" strokeDasharray="8 5"/><rect x={x} y={y} width="66" height="29" fill={color}/><text x={x+6} y={y+22} fontSize="24" fill="white">{s.id}</text></g>})}</g>}
</svg>;
}