|
9 | 9 | } = $props(); |
10 | 10 | let open = $state(false); // Default to closed |
11 | 11 |
|
12 | | - /** @type {SvelteMap<string, Record<string, any>>} */ |
13 | | - let active_tools = $state(new SvelteMap()); |
| 12 | + /** @type {import('svelte').Component} */ |
| 13 | + let ActiveComponent = $state(null); |
14 | 14 | /** @type {HTMLElement} */ |
15 | 15 | let toolbar; |
16 | 16 | /** @type {HTMLElement} */ |
|
29 | 29 | * @param {import('./public').Tool} tool |
30 | 30 | */ |
31 | 31 | function toggle_tool(tool) { |
32 | | - const active = active_tools.has(tool.name); |
33 | | - if (!active) { |
34 | | - let mounted_component; |
35 | | - if (tool.component) mounted_component = mountTool(tool.component, tool.name, { tool }); |
36 | | -
|
37 | | - active_tools.set(tool.name, mounted_component); |
38 | | - if (tool.activate) tool.activate(); |
| 32 | + if (tool.component === ActiveComponent) { |
| 33 | + ActiveComponent = undefined; |
39 | 34 | } else { |
40 | | - const mounted_component = active_tools.get(tool.name); |
41 | | - if (tool.component && mounted_component) unmountTool(mounted_component, tool.name); |
42 | | -
|
43 | | - if (tool.deactivate) tool.deactivate(); |
44 | | - active_tools.delete(tool.name); |
| 35 | + ActiveComponent = tool.component; |
45 | 36 | } |
46 | 37 |
|
47 | | - if (active_tools.size === 0) toolbarPanels.style.display = 'none'; |
| 38 | + if (!ActiveComponent) toolbarPanels.style.display = 'none'; |
48 | 39 | else toolbarPanels.style.display = 'block'; |
49 | 40 | } |
50 | 41 |
|
51 | | - /** |
52 | | - * @param {import('svelte').Component} component |
53 | | - * @param {string} id |
54 | | - * @param {Record<string, any>} props |
55 | | - */ |
56 | | - function mountTool(component, id, props) { |
57 | | - if (document.getElementById(id) != null) { |
58 | | - throw Error(`${id} already exists, skipping`); |
59 | | - } |
60 | | -
|
61 | | - const el = document.createElement('div'); |
62 | | - el.setAttribute('id', `svelte-toolbar-${id}`); |
63 | | - toolbarPanels.appendChild(el); |
64 | | - const mounted_component = mount(component, { target: el, props }); |
65 | | -
|
66 | | - return mounted_component; |
67 | | - } |
68 | | -
|
69 | | - /** |
70 | | - * @param {string} id |
71 | | - * @param {Record<string, any>} component |
72 | | - */ |
73 | | - async function unmountTool(component, id) { |
74 | | - await unmount(component); |
75 | | -
|
76 | | - const el = document.getElementById(`svelte-toolbar-${id}`); |
77 | | - if (el) el.remove(); |
78 | | - } |
79 | | -
|
80 | 42 | /** |
81 | 43 | * @param {DragEvent} event |
82 | 44 | */ |
|
129 | 91 | {#if open} |
130 | 92 | <ul class="svelte-toolbar-tools"> |
131 | 93 | {#each config.tools as tool} |
132 | | - <li class:active={active_tools.has(tool.name)}> |
| 94 | + <li class:active={tool.component === ActiveComponent}> |
133 | 95 | <button onclick={() => toggle_tool(tool)} aria-label={tool.name}>{@html tool.icon}</button |
134 | 96 | > |
135 | 97 | </li> |
|
140 | 102 | <Icon /> |
141 | 103 | </button> |
142 | 104 | </div> |
143 | | -<div class="svelte-toolbar-panels" bind:this={toolbarPanels}></div> |
| 105 | +<div class="svelte-toolbar-panels" bind:this={toolbarPanels}> |
| 106 | + {#if ActiveComponent} |
| 107 | + <ActiveComponent /> |
| 108 | + {/if} |
| 109 | +</div> |
144 | 110 |
|
145 | 111 | <style> |
146 | 112 | .svelte-toolbar { |
|
0 commit comments