|
1 | 1 | <script lang="ts"> |
2 | 2 | import { onMount } from 'svelte'; |
3 | 3 | import { base } from '$app/paths'; |
4 | | - import { fly, scale } from 'svelte/transition'; |
5 | 4 | import { cubicOut } from 'svelte/easing'; |
6 | 5 | import FlowCanvas from '$lib/components/FlowCanvas.svelte'; |
7 | 6 | import SimulationPanel from '$lib/components/panels/SimulationPanel.svelte'; |
|
1304 | 1303 | {/snippet} |
1305 | 1304 |
|
1306 | 1305 | {#snippet viewActions(btn: string)} |
| 1306 | + {#if hiddenNodes.length > 0} |
| 1307 | + <!-- svelte-ignore a11y_no_static_element_interactions --> |
| 1308 | + <div |
| 1309 | + class="hidden-group" |
| 1310 | + onmouseenter={handleHiddenGroupEnter} |
| 1311 | + onmouseleave={handleHiddenGroupLeave} |
| 1312 | + > |
| 1313 | + <button |
| 1314 | + class="{btn} hidden-btn" |
| 1315 | + use:tooltip={`${hiddenNodes.length} hidden node${hiddenNodes.length === 1 ? '' : 's'}`} |
| 1316 | + aria-label="Hidden nodes" |
| 1317 | + > |
| 1318 | + <Icon name="eye-off" size={16} /> |
| 1319 | + <span class="hidden-badge">{hiddenNodes.length}</span> |
| 1320 | + </button> |
| 1321 | + {#if hiddenMenuOpen} |
| 1322 | + <div class="recent-menu" role="menu"> |
| 1323 | + <div class="recent-menu-header">Hidden nodes</div> |
| 1324 | + {#each hiddenNodes as node (node.id)} |
| 1325 | + <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions --> |
| 1326 | + <div class="recent-item" role="menuitem" tabindex="0" onclick={() => handleUnhide(node.id)}> |
| 1327 | + <Icon name="eye" size={14} /> |
| 1328 | + <span class="recent-name" title={node.name}>{node.name}</span> |
| 1329 | + <span class="hidden-type">{node.type}</span> |
| 1330 | + </div> |
| 1331 | + {/each} |
| 1332 | + {#if hiddenNodes.length > 1} |
| 1333 | + <div class="recent-divider"></div> |
| 1334 | + <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions --> |
| 1335 | + <div class="recent-item show-all" role="menuitem" tabindex="0" onclick={handleShowAll}> |
| 1336 | + <Icon name="eye" size={14} /> |
| 1337 | + <span class="recent-name">Show all</span> |
| 1338 | + </div> |
| 1339 | + {/if} |
| 1340 | + </div> |
| 1341 | + {/if} |
| 1342 | + </div> |
| 1343 | + {/if} |
1307 | 1344 | <button class={btn} class:active={showPinnedPreviews} onclick={() => pinnedPreviewsStore.toggle()} use:tooltip={{ text: "Pin Previews", shortcut: "P" }} aria-label="Pin Previews" data-tour="toolbar-pin-previews"> |
1308 | 1345 | <Icon name={showPinnedPreviews ? "pin-filled" : "pin"} size={16} /> |
1309 | 1346 | </button> |
|
1344 | 1381 | <SubsystemBreadcrumb /> |
1345 | 1382 | </div> |
1346 | 1383 |
|
1347 | | - <!-- Floating toolbar --> |
1348 | | - <!-- svelte-ignore a11y_no_static_element_interactions --> |
1349 | | - <div class="toolbar-container" transition:fly={{ y: -20, duration: 200 }} onmousedown={() => triggerClearSelection()}> |
1350 | | - <!-- Sim controls now live in the left rail; file ops + view actions live in the top nav bar. --> |
1351 | | - |
1352 | | - <!-- Hidden nodes --> |
1353 | | - {#if hiddenNodes.length > 0} |
1354 | | - <!-- svelte-ignore a11y_no_static_element_interactions --> |
1355 | | - <div |
1356 | | - class="toolbar-group hidden-group" |
1357 | | - onmouseenter={handleHiddenGroupEnter} |
1358 | | - onmouseleave={handleHiddenGroupLeave} |
1359 | | - > |
1360 | | - <button |
1361 | | - class="toolbar-btn hidden-btn" |
1362 | | - use:tooltip={`${hiddenNodes.length} hidden node${hiddenNodes.length === 1 ? '' : 's'}`} |
1363 | | - aria-label="Hidden nodes" |
1364 | | - > |
1365 | | - <Icon name="eye-off" size={16} /> |
1366 | | - <span class="hidden-badge">{hiddenNodes.length}</span> |
1367 | | - </button> |
1368 | | - {#if hiddenMenuOpen} |
1369 | | - <div class="recent-menu" role="menu"> |
1370 | | - <div class="recent-menu-header">Hidden nodes</div> |
1371 | | - {#each hiddenNodes as node (node.id)} |
1372 | | - <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions --> |
1373 | | - <div class="recent-item" role="menuitem" tabindex="0" onclick={() => handleUnhide(node.id)}> |
1374 | | - <Icon name="eye" size={14} /> |
1375 | | - <span class="recent-name" title={node.name}>{node.name}</span> |
1376 | | - <span class="hidden-type">{node.type}</span> |
1377 | | - </div> |
1378 | | - {/each} |
1379 | | - {#if hiddenNodes.length > 1} |
1380 | | - <div class="recent-divider"></div> |
1381 | | - <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions --> |
1382 | | - <div class="recent-item show-all" role="menuitem" tabindex="0" onclick={handleShowAll}> |
1383 | | - <Icon name="eye" size={14} /> |
1384 | | - <span class="recent-name">Show all</span> |
1385 | | - </div> |
1386 | | - {/if} |
1387 | | - </div> |
1388 | | - {/if} |
1389 | | - </div> |
1390 | | - {/if} |
1391 | | - </div> |
1392 | | - |
1393 | 1384 | <!-- Panel toggles (left edge) --> |
1394 | 1385 | <!-- svelte-ignore a11y_no_static_element_interactions --> |
1395 | 1386 | <div class="panel-toggles" onmousedown={() => triggerClearSelection()}> |
|
1848 | 1839 | /* Home button relies on .icon-btn for sizing/hover; small separator from file-ops. */ |
1849 | 1840 | .editor-nav .brand { margin-right: var(--space-xs); } |
1850 | 1841 | /* Push the top-anchored floating overlays below the fixed nav. */ |
1851 | | - .app.has-nav .toolbar-container { top: calc(var(--space-md) + var(--header-height)); } |
1852 | 1842 | .app.has-nav .subsystem-breadcrumb { top: calc(var(--space-md) + var(--header-height)); } |
1853 | 1843 | .app.has-nav .logo-overlay { top: calc(var(--space-md) + var(--header-height)); } |
1854 | 1844 |
|
|
1872 | 1862 | opacity: 0.8; |
1873 | 1863 | } |
1874 | 1864 |
|
1875 | | - /* Toolbar */ |
1876 | | - .toolbar-container { |
1877 | | - position: fixed; |
1878 | | - top: var(--space-md); |
1879 | | - left: 50%; |
1880 | | - transform: translateX(-50%); |
1881 | | - z-index: 100; |
1882 | | - display: flex; |
1883 | | - align-items: center; |
1884 | | - gap: var(--space-lg); |
1885 | | - } |
1886 | | -
|
1887 | | - .toolbar-group { |
1888 | | - display: flex; |
1889 | | - gap: var(--space-xs); |
1890 | | - } |
1891 | | -
|
1892 | 1865 | .toolbar-btn { |
1893 | 1866 | width: var(--header-height); |
1894 | 1867 | height: var(--header-height); |
|
2025 | 1998 | background: color-mix(in srgb, var(--error) 15%, transparent); |
2026 | 1999 | } |
2027 | 2000 |
|
2028 | | - /* Hidden-nodes group reuses .open-group/.recent-menu layout */ |
| 2001 | + /* Hidden-nodes group reuses .open-group/.recent-menu layout; it sits on |
| 2002 | + the right side of the nav, so the menu anchors right to stay on screen. */ |
2029 | 2003 | .hidden-group { |
2030 | 2004 | position: relative; |
2031 | 2005 | } |
2032 | 2006 |
|
| 2007 | + .hidden-group .recent-menu { |
| 2008 | + left: auto; |
| 2009 | + right: 0; |
| 2010 | + } |
| 2011 | +
|
2033 | 2012 | .hidden-btn { |
2034 | 2013 | position: relative; |
2035 | 2014 | } |
2036 | 2015 |
|
2037 | 2016 | .hidden-badge { |
2038 | 2017 | position: absolute; |
2039 | | - top: -4px; |
2040 | | - right: -4px; |
| 2018 | + top: 0; |
| 2019 | + right: 0; |
2041 | 2020 | min-width: 16px; |
2042 | 2021 | height: 16px; |
2043 | 2022 | padding: 0 4px; |
|
2049 | 2028 | display: flex; |
2050 | 2029 | align-items: center; |
2051 | 2030 | justify-content: center; |
2052 | | - box-shadow: 0 0 0 2px var(--surface); |
| 2031 | + box-shadow: 0 0 0 2px var(--surface-raised); |
2053 | 2032 | } |
2054 | 2033 |
|
2055 | 2034 | .hidden-type { |
|
2070 | 2049 |
|
2071 | 2050 | .mutation-badge { |
2072 | 2051 | position: absolute; |
2073 | | - top: -4px; |
2074 | | - right: -4px; |
| 2052 | + top: 0; |
| 2053 | + right: 0; |
2075 | 2054 | min-width: 16px; |
2076 | 2055 | height: 16px; |
2077 | 2056 | padding: 0 4px; |
|
0 commit comments