|
41 | 41 | .ring-glow { box-shadow: 0 0 0 1px rgba(122,255,238,.20), inset 0 0 0 1px rgba(255,255,255,.03); } |
42 | 42 | .neon-border { box-shadow: 0 0 0 1px rgba(103,168,255,.35), inset 0 0 0 1px rgba(255,255,255,.04); } |
43 | 43 | .badge img{ vertical-align: middle; } |
| 44 | + .badge{ display: inline-block; margin: 0.125rem 0; } |
44 | 45 | .kicker{ display:inline-block; border:1px solid rgba(103,168,255,.35); background:rgba(103,168,255,.10); padding:.25rem .6rem; border-radius:999px; font-size:.75rem; font-weight:700; color:#B8D4FF } |
45 | 46 | </style> |
46 | 47 | </head> |
|
258 | 259 |
|
259 | 260 | const BadgeLinks = ({ links }) => { |
260 | 261 | const items = []; |
261 | | - const controls = []; |
| 262 | + let hasRetry = false; |
262 | 263 |
|
263 | 264 | // VS Code — static pill + dynamic shields (can error/rate-limit) |
264 | 265 | if (links?.vscode) { |
|
276 | 277 | <img alt="rating" src="${ratingSrc}"> |
277 | 278 | </a>` |
278 | 279 | ); |
279 | | - |
280 | | - // manual retry (cache-bust) for shields hits |
281 | | - controls.push( |
282 | | - `<button class="ml-2 text-xs text-slate-300/80 hover:text-sky-200 underline" |
283 | | - onclick=" |
284 | | - const imgs = this.parentElement.querySelectorAll('img[alt^=vs], img[alt=rating]'); |
285 | | - imgs.forEach(img => { img.src = img.src.split('?')[0] + '?r=' + Math.random().toString(36).slice(2); }); |
286 | | - "> |
287 | | - retry |
288 | | - </button>` |
289 | | - ); |
| 280 | + hasRetry = true; |
290 | 281 | } |
291 | 282 |
|
292 | 283 | // npm — encode for scoped packages |
|
309 | 300 | ); |
310 | 301 | } |
311 | 302 |
|
312 | | - const html = (items.join("") || '<span class="text-slate-400">—</span>') + (controls.join("") || ""); |
| 303 | + const badgesHtml = items.join("") || '<span class="text-slate-400">—</span>'; |
| 304 | + |
313 | 305 | return React.createElement("div", { |
314 | | - className: "flex flex-wrap items-center gap-2", |
315 | | - dangerouslySetInnerHTML: { __html: html } |
316 | | - }); |
| 306 | + className: "relative" |
| 307 | + }, |
| 308 | + React.createElement("div", { |
| 309 | + className: "flex flex-wrap items-start gap-1.5 pr-6", |
| 310 | + dangerouslySetInnerHTML: { __html: badgesHtml } |
| 311 | + }), |
| 312 | + hasRetry && React.createElement("button", { |
| 313 | + className: "absolute top-0 right-0 w-5 h-5 text-slate-400 hover:text-sky-200 transition-colors", |
| 314 | + title: "Retry badges", |
| 315 | + onClick: () => { |
| 316 | + const imgs = document.querySelectorAll('img[alt^="vs marketplace"], img[alt="rating"]'); |
| 317 | + imgs.forEach(img => { |
| 318 | + img.src = img.src.split('?')[0] + '?r=' + Math.random().toString(36).slice(2); |
| 319 | + }); |
| 320 | + } |
| 321 | + }, |
| 322 | + React.createElement("svg", { |
| 323 | + width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" |
| 324 | + }, |
| 325 | + React.createElement("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }), |
| 326 | + React.createElement("path", { d: "M21 3v5h-5" }), |
| 327 | + React.createElement("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }), |
| 328 | + React.createElement("path", { d: "M3 21v-5h5" }) |
| 329 | + ) |
| 330 | + ) |
| 331 | + ); |
317 | 332 | }; |
318 | 333 |
|
319 | 334 | const FeatureList = ({ items }) => |
|
0 commit comments