iter(g253): 文档站组件卡支持一键复制 Markdown 参数表
This commit is contained in:
@@ -402,6 +402,10 @@ iframe.demo{width:100%;height:430px;border:1px dashed var(--border);border-radiu
|
||||
.sw code{color:var(--muted)}
|
||||
.sw span{font-size:12px;color:var(--muted)}
|
||||
.swatches{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:4px 20px}
|
||||
.comp h4{display:flex;align-items:center;gap:8px;justify-content:space-between}
|
||||
.copy{margin-left:auto;flex:none;padding:3px 10px;border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--muted);font:inherit;font-size:12px;cursor:pointer;transition:color .15s,border-color .15s}
|
||||
.copy:hover{color:var(--text);border-color:var(--accent)}
|
||||
.copy:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
|
||||
.empty{color:var(--muted);text-align:center;padding:40px 0}
|
||||
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
|
||||
footer{max-width:960px;margin:0 auto;padding:0 20px 40px;color:var(--muted);font-size:12px}
|
||||
@@ -424,9 +428,49 @@ function propsTable(c){
|
||||
}).join('');
|
||||
return '<table class="props"><tr><th>参数</th><th>类型</th><th>必填</th><th>默认值</th><th>说明</th></tr>'+rows+'</table>';
|
||||
}
|
||||
var ALLCOMPS=[];
|
||||
DATA.forEach(function(p){ (p.docs&&p.docs.components||[]).forEach(function(c){ ALLCOMPS.push(c); }); });
|
||||
var TICK=String.fromCharCode(96); // 反引号:生成器本身是模板串,这里不写裸反引号,避免把模板串提前截断
|
||||
function mdOf(c){
|
||||
var bar=String.fromCharCode(124); // 竖线:Markdown 表格分隔符的转义源
|
||||
var cell=function(v){ return String(v||'').split(bar).join('\\\\'+bar); }; // 输出 \\| 给 Markdown 表格转义
|
||||
var out='### '+c.id+' · '+(c.title||c.id)+'\\n\\n';
|
||||
if(c.props&&c.props.length){
|
||||
out+='| 参数 | 类型 | 必填 | 说明 |\\n| --- | --- | --- | --- |\\n';
|
||||
c.props.forEach(function(p){ out+='| '+TICK+cell(p.n)+TICK+' | '+TICK+cell(p.t)+TICK+' | '+(p.r?'是':'否')+' | '+cell(p.d)+' |\\n'; });
|
||||
out+='\\n';
|
||||
}
|
||||
if(c.steps&&c.steps.length){
|
||||
out+='**用法**\\n\\n';
|
||||
c.steps.forEach(function(s,i){ out+=(i+1)+'. '+s+'\\n'; });
|
||||
out+='\\n';
|
||||
}
|
||||
if(c.example) out+=TICK+TICK+TICK+'ts\\n'+c.example+'\\n'+TICK+TICK+TICK+'\\n';
|
||||
return out;
|
||||
}
|
||||
function legacyCopy(text){
|
||||
var ta=document.createElement('textarea');
|
||||
ta.value=text; ta.setAttribute('readonly','');
|
||||
ta.style.position='fixed'; ta.style.opacity='0';
|
||||
document.body.appendChild(ta); ta.select();
|
||||
try { document.execCommand('copy'); } catch(e) {}
|
||||
document.body.removeChild(ta);
|
||||
}
|
||||
document.addEventListener('click',function(e){
|
||||
var btn=e.target.closest('[data-copy]');
|
||||
if(!btn) return;
|
||||
var c=ALLCOMPS.filter(function(x){return x.id===btn.getAttribute('data-copy')})[0];
|
||||
if(!c) return;
|
||||
var done=function(){ var old=btn.textContent; btn.textContent='已复制'; setTimeout(function(){ btn.textContent=old; },1200); };
|
||||
// 剪贴板 API 在 file:// 或未授权时会 reject,退回 textarea + execCommand
|
||||
if(navigator.clipboard&&navigator.clipboard.writeText){
|
||||
navigator.clipboard.writeText(mdOf(c)).then(done).catch(function(){ legacyCopy(mdOf(c)); done(); });
|
||||
} else { legacyCopy(mdOf(c)); done(); }
|
||||
});
|
||||
function compBlock(c){
|
||||
var steps=(c.steps||[]).map(function(s){return '<li>'+esc(s)+'</li>'}).join('');
|
||||
return '<div class="comp" id="c-'+esc(c.id)+'"><h4>'+esc(c.id)+' · '+esc(c.title||'')+'</h4>'
|
||||
return '<div class="comp" id="c-'+esc(c.id)+'"><h4>'+esc(c.id)+' · '+esc(c.title||'')
|
||||
+'<button class="copy" type="button" data-copy="'+esc(c.id)+'" title="复制为 Markdown 参数表,可直接贴进文档或 issue">复制参数表</button></h4>'
|
||||
+(c.props?propsTable(c):'')
|
||||
+(c.example?'<pre><code>'+esc(c.example)+'</code></pre>':'')
|
||||
+(steps?'<h5>手把手</h5><ol>'+steps+'</ol>':'')
|
||||
|
||||
Reference in New Issue
Block a user