Skip to content

Commit fb349d9

Browse files
committed
refactor(examples): render the vite hub dock with UnoCSS preset-icons
Replace the inline-SVG icon map with UnoCSS preset-icons (the vite-devtools approach): icons resolve to i-ph-* classes inlined offline from @iconify-json/ph. Restyle the shell with semantic light/dark shortcuts.
1 parent 6edc8c6 commit fb349d9

9 files changed

Lines changed: 148 additions & 365 deletions

File tree

examples/minimal-vite-devframe-hub/index.html

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,55 @@
11
<!doctype html>
2-
<html lang="en">
2+
<html lang="en" class="h-full">
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Minimal Vite Devframe Hub</title>
7-
<link rel="stylesheet" href="/src/client/style.css" />
7+
<script>
8+
// Follow the OS theme without a toggle (UnoCSS dark: is class-based).
9+
document.documentElement.classList.toggle(
10+
'dark',
11+
window.matchMedia('(prefers-color-scheme: dark)').matches,
12+
)
13+
</script>
814
</head>
9-
<body>
10-
<div class="app-shell">
11-
<header class="app-header">
12-
<h1>Minimal Vite Devframe Hub</h1>
13-
<p id="status"><span id="conn">Connecting…</span></p>
14-
<p class="app-tagline">a ~120-line, vite-devtools-style hub you can copy</p>
15+
<body class="h-full m0 of-hidden bg-base color-base font-sans">
16+
<div class="h-full flex flex-col">
17+
<header class="shrink-0 flex items-baseline gap-3 border-b border-base bg-base px4 py2.5">
18+
<h1 class="m0 text-sm font-600">Minimal Vite Devframe Hub</h1>
19+
<p id="status" class="m0 text-xs font-mono op-fade"><span id="conn">Connecting…</span></p>
20+
<p class="m0 ml-auto text-xs font-mono italic op-mute">a ~120-line, vite-devtools-style hub you can copy</p>
1521
</header>
1622

17-
<aside class="app-sidebar">
18-
<h2>Docks</h2>
19-
<ul id="docks"><li class="muted">Waiting for snapshot…</li></ul>
20-
</aside>
23+
<div class="grid grid-cols-[244px_1fr] min-h-0 flex-1">
24+
<aside class="flex flex-col gap-0.5 of-auto border-r border-base bg-secondary p2">
25+
<h2 class="panel-title px2 py1">Docks</h2>
26+
<ul id="docks" class="m0 flex flex-col list-none gap-0.5 p0">
27+
<li class="op-mute px2 text-sm">Waiting for snapshot…</li>
28+
</ul>
29+
</aside>
2130

22-
<main class="app-main">
23-
<iframe id="dock-iframe" src="about:blank" title="Selected dock"></iframe>
24-
</main>
31+
<main class="min-w-0 of-hidden bg-secondary">
32+
<iframe id="dock-iframe" src="about:blank" title="Selected dock" class="block h-full w-full border-0 bg-base"></iframe>
33+
</main>
34+
</div>
2535

26-
<footer class="app-footer">
27-
<section>
28-
<h2>Commands</h2>
29-
<ul id="commands"><li class="muted">Waiting for snapshot…</li></ul>
30-
<div class="actions">
31-
<button id="ping">Dispatch <code>minimal-vite-devframe-hub:ping</code></button>
36+
<footer class="grid grid-cols-3 shrink-0 gap-5 border-t border-base bg-base px4 py3 max-h-30vh of-auto">
37+
<section class="min-w-0">
38+
<h2 class="panel-title">Commands</h2>
39+
<ul id="commands" class="m0 flex flex-col list-none gap-1.5 p0"><li class="op-mute panel-row border-dashed">Waiting for snapshot…</li></ul>
40+
<div class="mt2.5">
41+
<button id="ping" class="btn-action text-xs">Dispatch <code class="font-mono op-fade">minimal-vite-devframe-hub:ping</code></button>
3242
</div>
3343
</section>
3444

35-
<section>
36-
<h2>Messages</h2>
37-
<ul id="messages"><li class="muted">No messages yet.</li></ul>
45+
<section class="min-w-0">
46+
<h2 class="panel-title">Messages</h2>
47+
<ul id="messages" class="m0 flex flex-col list-none gap-1.5 p0"><li class="op-mute panel-row border-dashed">No messages yet.</li></ul>
3848
</section>
3949

40-
<section>
41-
<h2>Terminals</h2>
42-
<ul id="terminals"><li class="muted">No terminal sessions.</li></ul>
50+
<section class="min-w-0">
51+
<h2 class="panel-title">Terminals</h2>
52+
<ul id="terminals" class="m0 flex flex-col list-none gap-1.5 p0"><li class="op-mute panel-row border-dashed">No terminal sessions.</li></ul>
4353
</section>
4454
</footer>
4555
</div>

examples/minimal-vite-devframe-hub/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
"devframe": "workspace:*"
2020
},
2121
"devDependencies": {
22+
"@iconify-json/ph": "catalog:frontend",
23+
"@unocss/vite": "catalog:frontend",
2224
"get-port-please": "catalog:deps",
2325
"pathe": "catalog:deps",
26+
"unocss": "catalog:frontend",
2427
"vite": "catalog:build"
2528
}
2629
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference types="vite/client" />
2+
3+
declare module 'virtual:uno.css'
Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,27 @@
1-
// Offline dock icons. SVG bodies are inlined from `@iconify-json/ph` — the
2-
// same Phosphor set vite-devtools uses — so the dock renders crisp glyphs with
3-
// no runtime network and no multi-megabyte icon-set dependency in the bundle.
4-
// To add an icon, copy its `body` from the `ph` set under a `ph:<name>` key.
5-
const ICONS: Record<string, string> = {
6-
'ph:git-branch-duotone': '<g fill="currentColor"><path d="M224 64a24 24 0 1 1-24-24a24 24 0 0 1 24 24" opacity=".2"/><path d="M232 64a32 32 0 1 0-40 31v17a8 8 0 0 1-8 8H96a23.8 23.8 0 0 0-8 1.38V95a32 32 0 1 0-16 0v66a32 32 0 1 0 16 0v-17a8 8 0 0 1 8-8h88a24 24 0 0 0 24-24V95a32.06 32.06 0 0 0 24-31M64 64a16 16 0 1 1 16 16a16 16 0 0 1-16-16m32 128a16 16 0 1 1-16-16a16 16 0 0 1 16 16M200 80a16 16 0 1 1 16-16a16 16 0 0 1-16 16"/></g>',
7-
'ph:terminal-window-duotone': '<g fill="currentColor"><path d="M224 56v144a8 8 0 0 1-8 8H40a8 8 0 0 1-8-8V56a8 8 0 0 1 8-8h176a8 8 0 0 1 8 8" opacity=".2"/><path d="M128 128a8 8 0 0 1-3 6.25l-40 32a8 8 0 1 1-10-12.5L107.19 128L75 102.25a8 8 0 1 1 10-12.5l40 32a8 8 0 0 1 3 6.25m48 24h-40a8 8 0 0 0 0 16h40a8 8 0 0 0 0-16m56-96v144a16 16 0 0 1-16 16H40a16 16 0 0 1-16-16V56a16 16 0 0 1 16-16h176a16 16 0 0 1 16 16m-16 144V56H40v144z"/></g>',
8-
'ph:code-duotone': '<g fill="currentColor"><path d="m240 128l-48 40H64l-48-40l48-40h128Z" opacity=".2"/><path d="M69.12 94.15L28.5 128l40.62 33.85a8 8 0 1 1-10.24 12.29l-48-40a8 8 0 0 1 0-12.29l48-40a8 8 0 0 1 10.24 12.3m176 27.7l-48-40a8 8 0 1 0-10.24 12.3L227.5 128l-40.62 33.85a8 8 0 1 0 10.24 12.29l48-40a8 8 0 0 0 0-12.29m-82.39-89.37a8 8 0 0 0-10.25 4.79l-64 176a8 8 0 0 0 4.79 10.26A8.1 8.1 0 0 0 96 224a8 8 0 0 0 7.52-5.27l64-176a8 8 0 0 0-4.79-10.25"/></g>',
9-
'ph:stethoscope-duotone': '<g fill="currentColor"><path d="M240 160a32 32 0 1 1-32-32a32 32 0 0 1 32 32" opacity=".2"/><path d="M220 160a12 12 0 1 1-12-12a12 12 0 0 1 12 12m-4.55 39.29A48.08 48.08 0 0 1 168 240h-24a48.05 48.05 0 0 1-48-48v-40.51A64 64 0 0 1 40 88V40a8 8 0 0 1 8-8h24a8 8 0 0 1 0 16H56v40a48 48 0 0 0 48.64 48c26.11-.34 47.36-22.25 47.36-48.83V48h-16a8 8 0 0 1 0-16h24a8 8 0 0 1 8 8v47.17c0 32.84-24.53 60.29-56 64.31V192a32 32 0 0 0 32 32h24a32.06 32.06 0 0 0 31.22-25a40 40 0 1 1 16.23.27ZM232 160a24 24 0 1 0-24 24a24 24 0 0 0 24-24"/></g>',
10-
'ph:wheelchair-duotone': '<g fill="currentColor"><path d="M128 48a24 24 0 1 1-24-24a24 24 0 0 1 24 24" opacity=".2"/><path d="M255.59 189.47a8 8 0 0 0-10.12-5.06l-17.42 5.81l-28.9-57.8A8 8 0 0 0 192 128h-80v-24h56a8 8 0 0 0 0-16h-56v-9a32 32 0 1 0-16 0v10.81A72 72 0 0 0 112 232c33.52 0 63.69-22.71 71.75-54a8 8 0 1 0-15.5-4c-6.16 24-30.34 42-56.25 42a56 56 0 0 1-16-109.66V136a8 8 0 0 0 8 8h83.05l29.79 59.58a8 8 0 0 0 9.69 4l24-8a8 8 0 0 0 5.06-10.11M88 48a16 16 0 1 1 16 16a16 16 0 0 1-16-16"/></g>',
11-
'ph:rocket-duotone': '<g fill="currentColor"><path d="m94.81 192l-29.45 22.24a8 8 0 0 1-12.81-4.51L40.19 154.1a8 8 0 0 1 1.66-6.86l30.31-36.33C71 134.25 76.7 161.43 94.81 192m119.34-44.76l-30.31-36.33c1.21 23.34-4.54 50.52-22.65 81.09l29.45 22.24a8 8 0 0 0 12.81-4.51l12.36-55.63a8 8 0 0 0-1.66-6.86" opacity=".2"/><path d="M152 224a8 8 0 0 1-8 8h-32a8 8 0 0 1 0-16h32a8 8 0 0 1 8 8m-24-112a12 12 0 1 0-12-12a12 12 0 0 0 12 12m95.62 43.83l-12.36 55.63a16 16 0 0 1-25.51 9.11L158.51 200h-61l-27.26 20.57a16 16 0 0 1-25.51-9.11l-12.36-55.63a16.09 16.09 0 0 1 3.32-13.71l28.56-34.26a123 123 0 0 1 8.57-36.67c12.9-32.34 36-52.63 45.37-59.85a16 16 0 0 1 19.6 0c9.34 7.22 32.47 27.51 45.37 59.85a123 123 0 0 1 8.57 36.67l28.56 34.26a16.09 16.09 0 0 1 3.32 13.71M99.43 184h57.14c21.12-37.54 25.07-73.48 11.74-106.88C156.55 47.64 134.49 29 128 24c-6.51 5-28.57 23.64-40.33 53.12c-13.31 33.4-9.36 69.34 11.76 106.88m-15 5.85q-16.15-29.35-19.6-57.69L48 152.36L60.36 208l.18-.13ZM208 152.36l-16.83-20.2q-3.42 28.28-19.56 57.69l23.85 18l.18.13Z"/></g>',
12-
'ph:wrench-duotone': '<g fill="currentColor"><path d="M224 96a64 64 0 0 1-94.94 56L73 217a24 24 0 0 1-34-34l65-56.06a64 64 0 0 1 80-90.29L144 80l5.66 26.34L176 112l43.35-40A63.8 63.8 0 0 1 224 96" opacity=".2"/><path d="M226.76 69a8 8 0 0 0-12.84-2.88l-40.3 37.19l-17.23-3.7l-3.7-17.23l37.19-40.3A8 8 0 0 0 187 29.24A72 72 0 0 0 88 96a72.3 72.3 0 0 0 6 28.94L33.79 177c-.15.12-.29.26-.43.39a32 32 0 0 0 45.26 45.26c.13-.13.27-.28.39-.42L131.06 162A72 72 0 0 0 232 96a71.6 71.6 0 0 0-5.24-27M160 152a56.14 56.14 0 0 1-27.07-7a8 8 0 0 0-9.92 1.77l-55.9 64.74a16 16 0 0 1-22.62-22.62L109.18 133a8 8 0 0 0 1.77-9.93a56 56 0 0 1 58.36-82.31l-31.2 33.81a8 8 0 0 0-1.94 7.1l5.66 26.33a8 8 0 0 0 6.14 6.14l26.35 5.66a8 8 0 0 0 7.1-1.94l33.81-31.2A56.06 56.06 0 0 1 160 152"/></g>',
13-
'ph:plug-duotone': '<g fill="currentColor"><path d="m212 132l-58.63 58.63a32 32 0 0 1-45.25 0l-42.75-42.75a32 32 0 0 1 0-45.25L124 44Z" opacity=".2"/><path d="M237.66 66.34a8 8 0 0 0-11.32 0L192 100.69L155.31 64l34.35-34.34a8 8 0 1 0-11.32-11.32L144 52.69l-26.34-26.35a8 8 0 0 0-11.32 11.32l6.35 6.34l-53 53a40 40 0 0 0 0 56.57l15.71 15.71l-49.06 49.06a8 8 0 0 0 11.32 11.32l49.09-49.09l15.71 15.71a40 40 0 0 0 56.57 0l53-53l6.34 6.35a8 8 0 0 0 11.32-11.32L203.31 112l34.35-34.34a8 8 0 0 0 0-11.32M147.72 185a24 24 0 0 1-33.95 0L71 142.23a24 24 0 0 1 0-33.95l53-53L200.69 132Z"/></g>',
14-
'ph:gear-duotone': '<g fill="currentColor"><path d="m207.86 123.18l16.78-21a99 99 0 0 0-10.07-24.29l-26.7-3a81 81 0 0 0-6.81-6.81l-3-26.71a99.4 99.4 0 0 0-24.3-10l-21 16.77a82 82 0 0 0-9.64 0l-21-16.78a99 99 0 0 0-24.21 10.07l-3 26.7a81 81 0 0 0-6.81 6.81l-26.71 3a99.4 99.4 0 0 0-10 24.3l16.77 21a82 82 0 0 0 0 9.64l-16.78 21a99 99 0 0 0 10.07 24.29l26.7 3a81 81 0 0 0 6.81 6.81l3 26.71a99.4 99.4 0 0 0 24.3 10l21-16.77a82 82 0 0 0 9.64 0l21 16.78a99 99 0 0 0 24.29-10.07l3-26.7a81 81 0 0 0 6.81-6.81l26.71-3a99.4 99.4 0 0 0 10-24.3l-16.77-21a82 82 0 0 0-.08-9.64M128 168a40 40 0 1 1 40-40a40 40 0 0 1-40 40" opacity=".2"/><path d="M128 80a48 48 0 1 0 48 48a48.05 48.05 0 0 0-48-48m0 80a32 32 0 1 1 32-32a32 32 0 0 1-32 32m88-29.84q.06-2.16 0-4.32l14.92-18.64a8 8 0 0 0 1.48-7.06a107.6 107.6 0 0 0-10.88-26.25a8 8 0 0 0-6-3.93l-23.72-2.64q-1.48-1.56-3-3L186 40.54a8 8 0 0 0-3.94-6a107.3 107.3 0 0 0-26.25-10.86a8 8 0 0 0-7.06 1.48L130.16 40h-4.32L107.2 25.11a8 8 0 0 0-7.06-1.48a107.6 107.6 0 0 0-26.25 10.88a8 8 0 0 0-3.93 6l-2.64 23.76q-1.56 1.49-3 3L40.54 70a8 8 0 0 0-6 3.94a107.7 107.7 0 0 0-10.87 26.25a8 8 0 0 0 1.49 7.06L40 125.84v4.32L25.11 148.8a8 8 0 0 0-1.48 7.06a107.6 107.6 0 0 0 10.88 26.25a8 8 0 0 0 6 3.93l23.72 2.64q1.49 1.56 3 3L70 215.46a8 8 0 0 0 3.94 6a107.7 107.7 0 0 0 26.25 10.87a8 8 0 0 0 7.06-1.49L125.84 216q2.16.06 4.32 0l18.64 14.92a8 8 0 0 0 7.06 1.48a107.2 107.2 0 0 0 26.25-10.88a8 8 0 0 0 3.93-6l2.64-23.72q1.56-1.48 3-3l23.78-2.8a8 8 0 0 0 6-3.94a107.7 107.7 0 0 0 10.87-26.25a8 8 0 0 0-1.49-7.06Zm-16.1-6.5a74 74 0 0 1 0 8.68a8 8 0 0 0 1.74 5.48l14.19 17.73a91.6 91.6 0 0 1-6.23 15l-22.6 2.56a8 8 0 0 0-5.1 2.64a74 74 0 0 1-6.14 6.14a8 8 0 0 0-2.64 5.1l-2.51 22.58a91.3 91.3 0 0 1-15 6.23l-17.74-14.19a8 8 0 0 0-5-1.75h-.48a74 74 0 0 1-8.68 0a8.06 8.06 0 0 0-5.48 1.74l-17.78 14.2a91.6 91.6 0 0 1-15-6.23L82.89 187a8 8 0 0 0-2.64-5.1a74 74 0 0 1-6.14-6.14a8 8 0 0 0-5.1-2.64l-22.58-2.52a91.3 91.3 0 0 1-6.23-15l14.19-17.74a8 8 0 0 0 1.74-5.48a74 74 0 0 1 0-8.68a8 8 0 0 0-1.74-5.48L40.2 100.45a91.6 91.6 0 0 1 6.23-15L69 82.89a8 8 0 0 0 5.1-2.64a74 74 0 0 1 6.14-6.14A8 8 0 0 0 82.89 69l2.51-22.57a91.3 91.3 0 0 1 15-6.23l17.74 14.19a8 8 0 0 0 5.48 1.74a74 74 0 0 1 8.68 0a8.06 8.06 0 0 0 5.48-1.74l17.77-14.19a91.6 91.6 0 0 1 15 6.23L173.11 69a8 8 0 0 0 2.64 5.1a74 74 0 0 1 6.14 6.14a8 8 0 0 0 5.1 2.64l22.58 2.51a91.3 91.3 0 0 1 6.23 15l-14.19 17.74a8 8 0 0 0-1.74 5.53Z"/></g>',
15-
'ph:gauge-duotone': '<g fill="currentColor"><path d="M232 152v24a8 8 0 0 1-8 8H32a8 8 0 0 1-8-8v-22.87C24 95.65 70.15 48.2 127.63 48A104 104 0 0 1 232 152" opacity=".2"/><path d="M207.06 72.67A111.24 111.24 0 0 0 128 40h-.4C66.07 40.21 16 91 16 153.13V176a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-24a111.25 111.25 0 0 0-32.94-79.33M224 176H119.71l54.76-75.3a8 8 0 0 0-12.94-9.42L99.92 176H32v-22.87c0-3.08.15-6.12.43-9.13H56a8 8 0 0 0 0-16H35.27c10.32-38.86 44-68.24 84.73-71.66V80a8 8 0 0 0 16 0V56.33A96.14 96.14 0 0 1 221 128h-21a8 8 0 0 0 0 16h23.67c.21 2.65.33 5.31.33 8Z"/></g>',
1+
// @unocss-include
2+
// Map a devframe dock `icon` (e.g. `ph:git-branch-duotone`) to a UnoCSS
3+
// `preset-icons` class. Keeping the class strings literal lets UnoCSS
4+
// statically extract them and inline only these glyphs from `@iconify-json/ph`
5+
// at build time — the same icon strategy vite-devtools uses. Add a row here to
6+
// support another dock icon.
7+
const ICON_CLASS: Record<string, string> = {
8+
'ph:git-branch-duotone': 'i-ph-git-branch-duotone',
9+
'ph:terminal-window-duotone': 'i-ph-terminal-window-duotone',
10+
'ph:code-duotone': 'i-ph-code-duotone',
11+
'ph:stethoscope-duotone': 'i-ph-stethoscope-duotone',
12+
'ph:wheelchair-duotone': 'i-ph-wheelchair-duotone',
13+
'ph:rocket-duotone': 'i-ph-rocket-duotone',
14+
'ph:wrench-duotone': 'i-ph-wrench-duotone',
15+
'ph:plug-duotone': 'i-ph-plug-duotone',
1616
}
1717

1818
/**
19-
* Render a devframe dock `icon` (e.g. `ph:git-branch-duotone`) as an inline
20-
* SVG string. Returns an empty string for icons absent from {@link ICONS} so
21-
* the caller can fall back to a text glyph.
19+
* Resolve a dock icon to its UnoCSS class, or an empty string when the icon
20+
* isn't mapped (the caller falls back to a text initial).
2221
*/
23-
export function iconSvg(name: string | { light: string, dark: string } | undefined, size = 18): string {
22+
export function iconClass(name: string | { light: string, dark: string } | undefined): string {
2423
if (!name)
2524
return ''
2625
const id = typeof name === 'string' ? name : name.light
27-
const body = ICONS[id]
28-
if (!body)
29-
return ''
30-
return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 256 256" aria-hidden="true">${body}</svg>`
26+
return ICON_CLASS[id] ?? ''
3127
}

examples/minimal-vite-devframe-hub/src/client/main.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import type {
55
DevframeTerminalSession,
66
} from '@devframes/hub/types'
77
import { connectDevframe } from '@devframes/hub/client'
8-
import { iconSvg } from './icons'
8+
import { iconClass } from './icons'
9+
import 'virtual:uno.css'
910

1011
const HUB_BASE = '/__hub/'
1112

12-
const statusEl = document.querySelector<HTMLElement>('#status')!
1313
const connEl = document.querySelector<HTMLElement>('#conn')!
1414
const docksEl = document.querySelector<HTMLElement>('#docks')!
1515
const commandsEl = document.querySelector<HTMLElement>('#commands')!
@@ -20,26 +20,26 @@ const iframeEl = document.querySelector<HTMLIFrameElement>('#dock-iframe')!
2020

2121
let selectedDockId: string | null = null
2222

23-
function setStatus(text: string, klass?: 'ready' | 'error') {
24-
connEl.textContent = text
25-
statusEl.className = klass ?? ''
23+
function setStatus(text: string, kind?: 'ready' | 'error') {
24+
const color = kind === 'ready' ? 'color-primary-500' : kind === 'error' ? 'color-red-500' : 'op-mute'
25+
connEl.innerHTML = `<span class="dot ${color} mr-1.5 align-middle"></span>${text}`
2626
}
2727

2828
function renderList<T>(host: HTMLElement, items: readonly T[], render: (item: T) => string) {
2929
if (!items.length) {
30-
host.innerHTML = '<li class="muted">empty</li>'
30+
host.innerHTML = '<li class="op-mute panel-row border-dashed">empty</li>'
3131
return
3232
}
3333
host.innerHTML = items.map(render).join('')
3434
}
3535

3636
/** Render a dock icon, falling back to the title's initial when unknown. */
3737
function dockIcon(entry: DevframeDockEntry): string {
38-
const svg = iconSvg(entry.icon, 20)
39-
if (svg)
40-
return svg
38+
const cls = iconClass(entry.icon)
39+
if (cls)
40+
return `<span class="dock-ico ${cls}"></span>`
4141
const initial = (entry.title?.[0] ?? '?').toUpperCase()
42-
return `<span class="dock-initial">${initial}</span>`
42+
return `<span class="dock-ico"><span class="grid h-5 w-5 place-items-center rounded bg-active text-2.5 font-700">${initial}</span></span>`
4343
}
4444

4545
function isIframeDock(d: DevframeDockEntry): d is DevframeDockEntry & { type: 'iframe', url: string } {
@@ -67,13 +67,13 @@ async function main() {
6767
selectedDockId = iframeDocks[0].id
6868

6969
if (!iframeDocks.length) {
70-
docksEl.innerHTML = '<li class="muted">No iframe docks</li>'
70+
docksEl.innerHTML = '<li class="op-mute px2 text-sm">No iframe docks</li>'
7171
iframeEl.src = 'about:blank'
7272
return
7373
}
7474

7575
renderList(docksEl, iframeDocks, d =>
76-
`<li><button type="button" data-dock-id="${d.id}" class="dock-btn${d.id === selectedDockId ? ' active' : ''}" title="${d.title}"><span class="dock-ico">${dockIcon(d)}</span><span class="dock-label">${d.title}</span></button></li>`)
76+
`<li><button type="button" data-dock-id="${d.id}" class="dock-item${d.id === selectedDockId ? ' dock-item-active' : ''}" title="${d.title}">${dockIcon(d)}<span class="truncate">${d.title}</span></button></li>`)
7777

7878
const selected = iframeDocks.find(d => d.id === selectedDockId)
7979
if (selected && iframeEl.getAttribute('src') !== selected.url)
@@ -100,7 +100,7 @@ async function main() {
100100
{ initialValue: [] },
101101
)
102102
const renderCommands = () => renderList(commandsEl, commands.value() ?? [], c =>
103-
`<li><strong>${c.title}</strong> <code>${c.id}</code></li>`)
103+
`<li class="panel-row">${c.title} <code class="op-fade">${c.id}</code></li>`)
104104
commands.on('updated', renderCommands)
105105
renderCommands()
106106

@@ -112,7 +112,7 @@ async function main() {
112112
'minimal-vite-devframe-hub:messages:list' as any,
113113
) as DevframeMessageEntry[]
114114
renderList(messagesEl, entries, m =>
115-
`<li><strong>[${m.level}]</strong> ${m.message}</li>`)
115+
`<li class="panel-row"><span class="op-fade">[${m.level}]</span> ${m.message}</li>`)
116116
}
117117
await refreshMessages()
118118

@@ -122,7 +122,7 @@ async function main() {
122122
'minimal-vite-devframe-hub:terminals:list' as any,
123123
) as Pick<DevframeTerminalSession, 'id' | 'title' | 'status' | 'description'>[]
124124
renderList(terminalsEl, sessions, t =>
125-
`<li><strong>${t.title}</strong> <code>${t.id}</code> · ${t.status}</li>`)
125+
`<li class="panel-row">${t.title} <code class="op-fade">${t.id}</code> · ${t.status}</li>`)
126126
}
127127
await refreshTerminals()
128128

0 commit comments

Comments
 (0)