|
6 | 6 | let selected = $state(''); |
7 | 7 | let selectedFormat = $state('yaml'); |
8 | 8 | let selections = $state<Record<string, string>>({}); |
| 9 | + let status = $state(''); |
9 | 10 | const config = $derived(description.configs.find(item => item.name === selected) ?? description.configs[0]); |
10 | 11 | const format = $derived(config?.formats.find(item => item.name === selectedFormat) ?? config?.formats[0]); |
11 | 12 | const lines = $derived(format?.lines.filter(line => line.conditions.every(([name, value]) => selections[name] === value)) ?? []); |
12 | 13 | const rendered = $derived(highlightLines(lines.map(line => line.text), format?.name ?? 'yaml')); |
13 | 14 |
|
14 | 15 | function selectConfig(name: string) { |
15 | 16 | selected = name; |
| 17 | + status = ''; |
16 | 18 | const next = description.configs.find(item => item.name === name); |
17 | 19 | selections = Object.fromEntries(next?.selectors.map(selector => [selector.name, selector.default]) ?? []); |
18 | 20 | if (next && !next.formats.some(item => item.name === selectedFormat)) selectedFormat = next.formats[0]?.name ?? ''; |
19 | 21 | } |
20 | 22 |
|
21 | 23 | function setSelection(name: string, value: string) { |
22 | 24 | selections = { ...selections, [name]: value }; |
| 25 | + status = ''; |
| 26 | + } |
| 27 | +
|
| 28 | + async function copy() { |
| 29 | + try { |
| 30 | + await navigator.clipboard.writeText(`${lines.map(line => line.text).join('\n')}\n`); |
| 31 | + status = '已复制当前显示的配置。'; |
| 32 | + } catch { |
| 33 | + status = '浏览器未允许复制,请手动选择文本。'; |
| 34 | + } |
23 | 35 | } |
24 | 36 |
|
25 | 37 | $effect(() => { |
|
47 | 59 | {#if config.formats.length > 1} |
48 | 60 | <label class="cg-desc-selector" for="cg-desc-format"> |
49 | 61 | <span>配置格式</span> |
50 | | - <select id="cg-desc-format" value={selectedFormat} onchange={(event) => selectedFormat = event.currentTarget.value}> |
| 62 | + <select id="cg-desc-format" value={selectedFormat} onchange={(event) => { selectedFormat = event.currentTarget.value; status = ''; }}> |
51 | 63 | {#each config.formats as item (item.name)}<option value={item.name}>{item.label}</option>{/each} |
52 | 64 | </select> |
53 | 65 | </label> |
|
66 | 78 | </aside> |
67 | 79 | {#if config && format} |
68 | 80 | <article class="cg-desc-document" aria-label={`${config.label} ${format.label} 配置详解`}> |
69 | | - <header><strong>{config.filename}.{format.extension}</strong><span>悬浮或聚焦任意配置项查看说明</span></header> |
| 81 | + <header> |
| 82 | + <strong>{config.filename}.{format.extension}</strong> |
| 83 | + <div class="cg-desc-meta"> |
| 84 | + <span>悬浮或聚焦任意配置项查看说明</span> |
| 85 | + <button type="button" onclick={copy}>复制配置</button> |
| 86 | + </div> |
| 87 | + </header> |
| 88 | + <p class="cg-desc-status" role="status" aria-live="polite">{status}</p> |
70 | 89 | <div class="cg-desc-code"> |
71 | 90 | {#each lines as line, index (`${line.text}-${index}`)} |
72 | 91 | <button type="button" class="cg-desc-line" aria-label={`${line.text}。${line.description}`}> |
|
0 commit comments