rework toolbar to single active tool

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

@ -9,8 +9,8 @@
} = $props();
let open = $state(false); // Default to closed
/** @type {SvelteMap<string, Record<string, any>>} */
let active_tools = $state(new SvelteMap());
/** @type {import('svelte').Component} */
let ActiveComponent = $state(null);
/** @type {HTMLElement} */
let toolbar;
/** @type {HTMLElement} */
@ -29,54 +29,16 @@
* @param {import('./public').Tool} tool
*/
function toggle_tool(tool) {
const active = active_tools.has(tool.name);
if (!active) {
let mounted_component;
if (tool.component) mounted_component = mountTool(tool.component, tool.name, { tool });
active_tools.set(tool.name, mounted_component);
if (tool.activate) tool.activate();
if (tool.component === ActiveComponent) {
ActiveComponent = undefined;
} else {
const mounted_component = active_tools.get(tool.name);
if (tool.component && mounted_component) unmountTool(mounted_component, tool.name);
if (tool.deactivate) tool.deactivate();
active_tools.delete(tool.name);
ActiveComponent = tool.component;
}
if (active_tools.size === 0) toolbarPanels.style.display = 'none';
if (!ActiveComponent) toolbarPanels.style.display = 'none';
else toolbarPanels.style.display = 'block';
}
/**
* @param {import('svelte').Component} component
* @param {string} id
* @param {Record<string, any>} props
*/
function mountTool(component, id, props) {
if (document.getElementById(id) != null) {
throw Error(`${id} already exists, skipping`);
}
const el = document.createElement('div');
el.setAttribute('id', `svelte-toolbar-${id}`);
toolbarPanels.appendChild(el);
const mounted_component = mount(component, { target: el, props });
return mounted_component;
}
/**
* @param {string} id
* @param {Record<string, any>} component
*/
async function unmountTool(component, id) {
await unmount(component);
const el = document.getElementById(`svelte-toolbar-${id}`);
if (el) el.remove();
}
/**
* @param {DragEvent} event
*/
@ -129,7 +91,7 @@
{#if open}
<ul class="svelte-toolbar-tools">
{#each config.tools as tool}
<li class:active={active_tools.has(tool.name)}>
<li class:active={tool.component === ActiveComponent}>
<button onclick={() => toggle_tool(tool)} aria-label={tool.name}>{@html tool.icon}</button
>
</li>
@ -140,7 +102,11 @@
<Icon />
</button>
</div>
<div class="svelte-toolbar-panels" bind:this={toolbarPanels}></div>
<div class="svelte-toolbar-panels" bind:this={toolbarPanels}>
{#if ActiveComponent}
<ActiveComponent />
{/if}
</div>
<style>
.svelte-toolbar {

Loading…
Cancel
Save