make the toolbar nicer

feat/devtool
Manuel Serret 4 months ago
parent fc5427dbb1
commit 5f84c2abb8

@ -1,6 +1,6 @@
<!-- Grabbed from https://github.com/sveltejs/branding/blob/master/svelte-logo.svg --> <!-- Grabbed from https://github.com/sveltejs/branding/blob/master/svelte-logo.svg -->
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128" <svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"
><title>svelte-logo</title><path ><title>svelte-inspector</title><path
d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157" d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157"
style="fill:#ff3e00" style="fill:#ff3e00"
/><path /><path

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -7,7 +7,7 @@
/** @type import('./public.d.ts').ResolvedConfig */ /** @type import('./public.d.ts').ResolvedConfig */
config config
} = $props(); } = $props();
let open = $state(true); // todo change this to false let open = $state(false); // Default to closed
/** @type {SvelteMap<string, Record<string, any>>} */ /** @type {SvelteMap<string, Record<string, any>>} */
let active_tools = $state(new SvelteMap()); let active_tools = $state(new SvelteMap());
@ -20,6 +20,8 @@
let dragOffsetY = 0; let dragOffsetY = 0;
onMount(() => { onMount(() => {
toolbar.style.right = '20px';
toolbar.style.bottom = '20px';
recalculate_toolbar_panel_position(); recalculate_toolbar_panel_position();
}); });
@ -33,14 +35,17 @@
if (tool.component) mounted_component = mountTool(tool.component, tool.name, { tool }); if (tool.component) mounted_component = mountTool(tool.component, tool.name, { tool });
active_tools.set(tool.name, mounted_component); active_tools.set(tool.name, mounted_component);
tool.activate(); if (tool.activate) tool.activate();
} else { } else {
const mounted_component = active_tools.get(tool.name); const mounted_component = active_tools.get(tool.name);
if (tool.component && mounted_component) unmountTool(mounted_component, tool.name); if (tool.component && mounted_component) unmountTool(mounted_component, tool.name);
tool.deactivate(); if (tool.deactivate) tool.deactivate();
active_tools.delete(tool.name); active_tools.delete(tool.name);
} }
if (active_tools.size === 0) toolbarPanels.style.display = 'none';
else toolbarPanels.style.display = 'block';
} }
/** /**
@ -99,24 +104,21 @@
async function toggle_toolbar() { async function toggle_toolbar() {
open = !open; open = !open;
// need to wait here, so that the toolbar can close first
await tick(); await tick();
recalculate_toolbar_panel_position(); recalculate_toolbar_panel_position();
} }
function recalculate_toolbar_panel_position() { function recalculate_toolbar_panel_position() {
const rect = toolbar.getBoundingClientRect(); const rect = toolbar.getBoundingClientRect();
toolbarPanels.style.right = toolbar.style.right; toolbarPanels.style.right = toolbar.style.right;
toolbarPanels.style.bottom = parseFloat(toolbar.style.bottom ?? 0) + rect.height + 'px'; toolbarPanels.style.bottom = parseFloat(toolbar.style.bottom ?? 0) + rect.height + 10 + 'px'; // Add a small gap
} }
</script> </script>
<svelte:window onresize={recalculate_toolbar_panel_position} /> <svelte:window onresize={recalculate_toolbar_panel_position} />
<div <div
class="toolbar" class="svelte-toolbar"
bind:this={toolbar} bind:this={toolbar}
draggable="true" draggable="true"
ondrag={drag} ondrag={drag}
@ -125,7 +127,7 @@
tabindex="-1" tabindex="-1"
> >
{#if open} {#if open}
<ul class="tools"> <ul class="svelte-toolbar-tools">
{#each config.tools as tool} {#each config.tools as tool}
<li class:active={active_tools.has(tool.name)}> <li class:active={active_tools.has(tool.name)}>
<button onclick={() => toggle_tool(tool)} aria-label={tool.name}>{@html tool.icon}</button <button onclick={() => toggle_tool(tool)} aria-label={tool.name}>{@html tool.icon}</button
@ -134,23 +136,44 @@
{/each} {/each}
</ul> </ul>
{/if} {/if}
<button type="button" class="toolbar-selector" onclick={toggle_toolbar}> <button type="button" class="svelte-toolbar-selector" onclick={toggle_toolbar}>
<Icon /> <Icon />
</button> </button>
</div> </div>
<div class="toolbar-panels" bind:this={toolbarPanels}></div> <div class="svelte-toolbar-panels" bind:this={toolbarPanels}></div>
<style> <style>
.toolbar-selector { .svelte-toolbar {
display: inline-flex;
background-color: var(--toolbar-background);
color: var(--toolbar-color);
position: fixed;
z-index: 1000;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
padding: 8px;
}
.svelte-toolbar-selector {
cursor: pointer; cursor: pointer;
background: none;
border: none;
padding: 8px;
border-radius: 6px;
transition: background-color 0.2s ease-in-out;
} }
.toolbar-selector :global(svg) { .svelte-toolbar-selector:hover {
width: 50px; background-color: var(--toolbar-selector-hover-background);
height: 50px;
} }
.tools { .svelte-toolbar-selector :global(svg) {
width: 24px;
height: 24px;
fill: var(--toolbar-icon-color);
}
.svelte-toolbar-tools {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -158,48 +181,88 @@
align-items: center; align-items: center;
} }
.tools li { .svelte-toolbar-tools li {
display: inline-block; display: inline-block;
background-color: #444; margin: 0 4px;
border: #111 1px solid;
border-radius: 50%;
margin: 0 10px;
height: 50px;
width: 50px;
}
.tools li.active {
border-color: #ff3e00;
} }
.tools li button { .svelte-toolbar-tools li button {
padding: 0; padding: 8px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 100%; width: 36px;
height: 100%; height: 36px;
border-radius: 50%;
border: none;
background-color: var(--tool-button-background);
color: var(--tool-button-color);
cursor: pointer;
transition:
background-color 0.2s ease-in-out,
border-color 0.2s ease-in-out;
} }
.tools li button :global(svg) { .svelte-toolbar-tools li button:hover {
height: 30px; background-color: var(--tool-button-hover-background);
width: 30px;
} }
.toolbar { .svelte-toolbar-tools li.active button {
display: inline-flex; border: 2px solid var(--accent-color);
background-color: #666; /* TODO: consider dark / light mode */ }
color: white;
position: fixed; .svelte-toolbar-tools li :global(svg) {
right: 0; filter: grayscale(100%);
bottom: 0; }
.svelte-toolbar-tools li.active :global(svg) {
filter: unset;
}
.svelte-toolbar-tools li button :global(svg) {
height: 20px;
width: 20px;
fill: var(--tool-icon-color);
} }
.toolbar-panels { .svelte-toolbar-panels {
position: fixed; position: fixed;
background-color: #999; z-index: 999;
right: 0; background-color: var(--panel-background);
bottom: 0; border-radius: 8px;
display: flex; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
padding: 16px;
display: none;
flex-direction: column;
gap: 8px;
color: var(--toolbar-color);
}
:root {
--toolbar-background: #f0f0f0;
--toolbar-color: #222;
--toolbar-selector-hover-background: #e0e0e0;
--toolbar-icon-color: #333;
--tool-button-background: #fff;
--tool-button-color: #333;
--tool-button-hover-background: #eee;
--tool-icon-color: #333;
--accent-color: #ff3e00;
--panel-background: #fff;
}
@media (prefers-color-scheme: dark) {
:root {
--toolbar-background: #1e1e27;
--toolbar-color: white;
--toolbar-selector-hover-background: #333344;
--toolbar-icon-color: #d4d4d8;
--tool-button-background: #333344;
--tool-button-color: #d4d4d8;
--tool-button-hover-background: #444;
--tool-icon-color: #d4d4d8;
--accent-color: #ff3e00;
--panel-background: #252531;
}
} }
</style> </style>

@ -10,39 +10,13 @@
</select> </select>
</label> </label>
</div> </div>
<div>
<label for="position"
>Position
<select id="position"> <style>
<option value="top-left">top left</option> select option {
<option value="top-left">top right</option> color: black;
<option value="top-left">bottom right</option> }
<option value="top-left">bottom left</option>
</select>
</label>
</div>
<div>
<label for="position"
>Position
<select id="position">
<option value="top-left">top left</option>
<option value="top-left">top right</option>
<option value="top-left">bottom right</option>
<option value="top-left">bottom left</option>
</select>
</label>
</div>
<div>
<label for="position"
>Position
<select id="position"> select:not(:checked) {
<option value="top-left">top left</option> color: var(--toolbar-color);
<option value="top-left">top right</option> }
<option value="top-left">bottom right</option> </style>
<option value="top-left">bottom left</option>
</select>
</label>
</div>

Loading…
Cancel
Save