@opentrace/components 0.1.1-rc.43 → 0.1.1-rc.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components.css +443 -0
- package/dist/opentrace-components.cjs +195 -2
- package/dist/opentrace-components.cjs.map +1 -1
- package/dist/opentrace-components.js +195 -2
- package/dist/opentrace-components.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/panels/GraphToolbar.d.ts +4 -0
- package/dist/src/panels/GraphToolbar.d.ts.map +1 -0
- package/dist/src/panels/index.d.ts +2 -1
- package/dist/src/panels/index.d.ts.map +1 -1
- package/dist/src/panels/types.d.ts +46 -0
- package/dist/src/panels/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/components.css
CHANGED
|
@@ -1385,6 +1385,28 @@
|
|
|
1385
1385
|
.graph-badge-sep {
|
|
1386
1386
|
margin: 0 3px;
|
|
1387
1387
|
}
|
|
1388
|
+
|
|
1389
|
+
/* ── Compact badge (1100px–1300px) ──────────── */
|
|
1390
|
+
@media (max-width: 1300px) and (min-width: 1100px) {
|
|
1391
|
+
.graph-badge-total,
|
|
1392
|
+
.graph-badge-label {
|
|
1393
|
+
display: none;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
.graph-badge {
|
|
1397
|
+
gap: 4px;
|
|
1398
|
+
padding: 0 10px;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
/* ── Hidden badge (1025px–1099px) ───────────── */
|
|
1403
|
+
/* Below 1024px the toolbar collapses to burger dropdown where the
|
|
1404
|
+
badge reappears as a full-width menu row, so we stop hiding at 1025px. */
|
|
1405
|
+
@media (max-width: 1099px) and (min-width: 1025px) {
|
|
1406
|
+
.graph-badge {
|
|
1407
|
+
display: none;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1388
1410
|
/*
|
|
1389
1411
|
* Copyright 2026 OpenTrace Contributors
|
|
1390
1412
|
*
|
|
@@ -1504,6 +1526,427 @@
|
|
|
1504
1526
|
* limitations under the License.
|
|
1505
1527
|
*/
|
|
1506
1528
|
|
|
1529
|
+
/* ── Toolbar layout ─────────────────────────── */
|
|
1530
|
+
|
|
1531
|
+
.ot-toolbar {
|
|
1532
|
+
position: absolute;
|
|
1533
|
+
top: 0;
|
|
1534
|
+
left: 0;
|
|
1535
|
+
right: 0;
|
|
1536
|
+
z-index: 10;
|
|
1537
|
+
display: flex;
|
|
1538
|
+
align-items: center;
|
|
1539
|
+
gap: 12px;
|
|
1540
|
+
padding: 16px 24px;
|
|
1541
|
+
pointer-events: none;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
.ot-toolbar h1 {
|
|
1545
|
+
margin: 0;
|
|
1546
|
+
font-size: 1.25rem;
|
|
1547
|
+
font-weight: 600;
|
|
1548
|
+
color: var(--foreground);
|
|
1549
|
+
letter-spacing: -0.02em;
|
|
1550
|
+
pointer-events: auto;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
/* ── Nav (inline on desktop, dropdown on mobile) */
|
|
1554
|
+
|
|
1555
|
+
.ot-toolbar-nav {
|
|
1556
|
+
display: flex;
|
|
1557
|
+
align-items: center;
|
|
1558
|
+
gap: 12px;
|
|
1559
|
+
flex: 1;
|
|
1560
|
+
pointer-events: auto;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
/* Hidden on desktop */
|
|
1564
|
+
.ot-toolbar .ot-menu-label {
|
|
1565
|
+
display: none;
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
.ot-toolbar .ot-mobile-panel-btn,
|
|
1569
|
+
.ot-toolbar .ot-menu-divider {
|
|
1570
|
+
display: none;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
/* ── Search placement ──────────────────────── */
|
|
1574
|
+
/* Desktop: search inside nav is visible, tablet search is hidden */
|
|
1575
|
+
.ot-toolbar .ot-search-tablet {
|
|
1576
|
+
display: none;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
.ot-toolbar .ot-search-nav {
|
|
1580
|
+
display: contents;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
/* ── Persistent actions ─────────────────────── */
|
|
1584
|
+
/* On desktop: hidden here, shown inside nav via .ot-persistent-desktop */
|
|
1585
|
+
.ot-toolbar .ot-persistent-mobile {
|
|
1586
|
+
display: none;
|
|
1587
|
+
pointer-events: auto;
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
.ot-toolbar .ot-persistent-desktop {
|
|
1591
|
+
display: contents;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
/* ── Burger button ──────────────────────────── */
|
|
1595
|
+
|
|
1596
|
+
.ot-toolbar .ot-burger-btn {
|
|
1597
|
+
display: none;
|
|
1598
|
+
background: var(--card);
|
|
1599
|
+
border: 1px solid var(--border);
|
|
1600
|
+
border-radius: 8px;
|
|
1601
|
+
padding: 6px;
|
|
1602
|
+
cursor: pointer;
|
|
1603
|
+
color: var(--foreground);
|
|
1604
|
+
pointer-events: auto;
|
|
1605
|
+
flex-shrink: 0;
|
|
1606
|
+
margin-left: auto;
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
.ot-toolbar .ot-burger-btn:hover {
|
|
1610
|
+
background: var(--accent);
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
/* ── Search ─────────────────────────────────── */
|
|
1614
|
+
|
|
1615
|
+
.ot-toolbar .ot-search-container {
|
|
1616
|
+
position: relative;
|
|
1617
|
+
flex: 1;
|
|
1618
|
+
max-width: 460px;
|
|
1619
|
+
margin: 0 0.5rem;
|
|
1620
|
+
pointer-events: auto;
|
|
1621
|
+
display: flex;
|
|
1622
|
+
align-items: center;
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
.ot-toolbar .ot-search-input {
|
|
1626
|
+
width: 100%;
|
|
1627
|
+
height: 36px;
|
|
1628
|
+
padding: 0 12px;
|
|
1629
|
+
padding-right: 155px;
|
|
1630
|
+
background: color-mix(in oklch, var(--card) 80%, transparent);
|
|
1631
|
+
border: 1px solid color-mix(in oklch, var(--border) 30%, transparent);
|
|
1632
|
+
border-radius: calc(var(--radius) + 2px);
|
|
1633
|
+
color: var(--foreground);
|
|
1634
|
+
font-size: 0.8rem;
|
|
1635
|
+
transition: all 0.2s;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
.ot-toolbar .ot-search-input:focus {
|
|
1639
|
+
outline: none;
|
|
1640
|
+
border-color: color-mix(in oklch, var(--primary) 50%, transparent);
|
|
1641
|
+
box-shadow: 0 0 0 2px color-mix(in oklch, var(--primary) 12%, transparent);
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
.ot-toolbar .ot-search-input::placeholder {
|
|
1645
|
+
color: var(--muted-foreground);
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
.ot-toolbar .ot-search-params {
|
|
1649
|
+
position: absolute;
|
|
1650
|
+
right: 56px;
|
|
1651
|
+
display: flex;
|
|
1652
|
+
align-items: center;
|
|
1653
|
+
gap: 6px;
|
|
1654
|
+
font-size: 0.7rem;
|
|
1655
|
+
color: var(--muted-foreground);
|
|
1656
|
+
border-left: 1px solid color-mix(in oklch, var(--border) 30%, transparent);
|
|
1657
|
+
padding-left: 8px;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
.ot-toolbar .ot-hops-input {
|
|
1661
|
+
width: 32px;
|
|
1662
|
+
height: 22px;
|
|
1663
|
+
background: color-mix(in oklch, var(--background) 60%, transparent);
|
|
1664
|
+
border: 1px solid color-mix(in oklch, var(--border) 25%, transparent);
|
|
1665
|
+
border-radius: calc(var(--radius) - 2px);
|
|
1666
|
+
color: var(--foreground);
|
|
1667
|
+
font-size: 0.7rem;
|
|
1668
|
+
padding: 0 4px;
|
|
1669
|
+
text-align: center;
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
.ot-toolbar .ot-hops-input:focus {
|
|
1673
|
+
outline: none;
|
|
1674
|
+
border-color: var(--primary);
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
.ot-toolbar .ot-hops-input::-webkit-inner-spin-button,
|
|
1678
|
+
.ot-toolbar .ot-hops-input::-webkit-outer-spin-button {
|
|
1679
|
+
-webkit-appearance: none;
|
|
1680
|
+
margin: 0;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
.ot-toolbar .ot-search-actions {
|
|
1684
|
+
position: absolute;
|
|
1685
|
+
right: 6px;
|
|
1686
|
+
top: 50%;
|
|
1687
|
+
transform: translateY(-50%);
|
|
1688
|
+
display: flex;
|
|
1689
|
+
align-items: center;
|
|
1690
|
+
gap: 2px;
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
.ot-toolbar .ot-clear-search {
|
|
1694
|
+
background: none;
|
|
1695
|
+
border: none;
|
|
1696
|
+
color: var(--muted-foreground);
|
|
1697
|
+
font-size: 1rem;
|
|
1698
|
+
cursor: pointer;
|
|
1699
|
+
padding: 2px;
|
|
1700
|
+
line-height: 1;
|
|
1701
|
+
display: flex;
|
|
1702
|
+
align-items: center;
|
|
1703
|
+
justify-content: center;
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
.ot-toolbar .ot-clear-search:hover {
|
|
1707
|
+
color: var(--foreground);
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
.ot-toolbar .ot-search-btn {
|
|
1711
|
+
background: var(--primary);
|
|
1712
|
+
border: none;
|
|
1713
|
+
border-radius: calc(var(--radius) - 2px);
|
|
1714
|
+
color: var(--primary-foreground);
|
|
1715
|
+
width: 24px;
|
|
1716
|
+
height: 24px;
|
|
1717
|
+
cursor: pointer;
|
|
1718
|
+
display: flex;
|
|
1719
|
+
align-items: center;
|
|
1720
|
+
justify-content: center;
|
|
1721
|
+
transition: background 0.15s;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
.ot-toolbar .ot-search-btn:hover:not(:disabled) {
|
|
1725
|
+
background: color-mix(in oklch, var(--primary) 85%, black);
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
.ot-toolbar .ot-search-btn:disabled {
|
|
1729
|
+
background: color-mix(in oklch, var(--secondary) 60%, transparent);
|
|
1730
|
+
color: var(--muted-foreground);
|
|
1731
|
+
cursor: not-allowed;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
/* ── Reset / Show All button ────────────────── */
|
|
1735
|
+
|
|
1736
|
+
.ot-toolbar .ot-reset-btn {
|
|
1737
|
+
pointer-events: auto;
|
|
1738
|
+
background: color-mix(in oklch, var(--card) 80%, transparent);
|
|
1739
|
+
border: 1px solid color-mix(in oklch, var(--border) 30%, transparent);
|
|
1740
|
+
color: var(--muted-foreground);
|
|
1741
|
+
height: 36px;
|
|
1742
|
+
padding: 0 12px;
|
|
1743
|
+
border-radius: calc(var(--radius) + 2px);
|
|
1744
|
+
font-size: 0.75rem;
|
|
1745
|
+
cursor: pointer;
|
|
1746
|
+
transition: all 0.2s;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
.ot-toolbar .ot-reset-btn:hover {
|
|
1750
|
+
background: color-mix(in oklch, var(--primary) 10%, transparent);
|
|
1751
|
+
color: var(--primary);
|
|
1752
|
+
border-color: color-mix(in oklch, var(--primary) 30%, transparent);
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
/* ── Tablet + Mobile (≤ 1024px): burger dropdown ── */
|
|
1756
|
+
|
|
1757
|
+
@media (max-width: 1024px) {
|
|
1758
|
+
.ot-toolbar {
|
|
1759
|
+
flex-wrap: wrap;
|
|
1760
|
+
padding: max(12px, env(safe-area-inset-top))
|
|
1761
|
+
max(16px, env(safe-area-inset-right)) 12px
|
|
1762
|
+
max(16px, env(safe-area-inset-left));
|
|
1763
|
+
gap: 0;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
/* Tablet search: visible outside the nav at 600–1024px */
|
|
1767
|
+
.ot-toolbar .ot-search-tablet {
|
|
1768
|
+
display: flex;
|
|
1769
|
+
flex: 1;
|
|
1770
|
+
min-width: 0;
|
|
1771
|
+
pointer-events: auto;
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
.ot-toolbar .ot-search-tablet .ot-search-container {
|
|
1775
|
+
flex: 1;
|
|
1776
|
+
max-width: none;
|
|
1777
|
+
margin: 0 8px;
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
/* Hide the in-nav copy of search */
|
|
1781
|
+
.ot-toolbar .ot-search-nav {
|
|
1782
|
+
display: none;
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
.ot-toolbar .ot-persistent-mobile {
|
|
1786
|
+
display: flex;
|
|
1787
|
+
align-items: center;
|
|
1788
|
+
gap: 8px;
|
|
1789
|
+
margin-left: 0;
|
|
1790
|
+
flex-shrink: 0;
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
.ot-toolbar .ot-persistent-desktop {
|
|
1794
|
+
display: none;
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
.ot-toolbar .ot-burger-btn {
|
|
1798
|
+
display: flex;
|
|
1799
|
+
align-items: center;
|
|
1800
|
+
justify-content: center;
|
|
1801
|
+
margin-left: 8px;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
.ot-toolbar-nav {
|
|
1805
|
+
display: none;
|
|
1806
|
+
flex-basis: 100%;
|
|
1807
|
+
flex-direction: column;
|
|
1808
|
+
align-items: stretch;
|
|
1809
|
+
gap: 0;
|
|
1810
|
+
background: var(--card);
|
|
1811
|
+
border: 1px solid var(--border);
|
|
1812
|
+
border-radius: calc(var(--radius) + 2px);
|
|
1813
|
+
padding: 6px 0;
|
|
1814
|
+
margin-top: 8px;
|
|
1815
|
+
pointer-events: auto;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
.ot-toolbar-nav.open {
|
|
1819
|
+
display: flex;
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
/* Show panel shortcuts and dividers */
|
|
1823
|
+
.ot-toolbar .ot-mobile-panel-btn {
|
|
1824
|
+
display: flex;
|
|
1825
|
+
align-items: center;
|
|
1826
|
+
gap: 10px;
|
|
1827
|
+
padding: 10px 16px;
|
|
1828
|
+
background: transparent;
|
|
1829
|
+
border: none;
|
|
1830
|
+
color: var(--foreground);
|
|
1831
|
+
cursor: pointer;
|
|
1832
|
+
font-size: 14px;
|
|
1833
|
+
font-weight: 500;
|
|
1834
|
+
pointer-events: auto;
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
.ot-toolbar .ot-mobile-panel-btn:hover {
|
|
1838
|
+
background: var(--accent);
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
.ot-toolbar .ot-menu-divider {
|
|
1842
|
+
display: block;
|
|
1843
|
+
height: 1px;
|
|
1844
|
+
background: var(--border);
|
|
1845
|
+
margin: 4px 0;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
.ot-toolbar .ot-menu-label {
|
|
1849
|
+
display: inline;
|
|
1850
|
+
font-size: 14px;
|
|
1851
|
+
font-weight: 500;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
/* Search full width in dropdown */
|
|
1855
|
+
.ot-toolbar-nav .ot-search-container {
|
|
1856
|
+
width: auto;
|
|
1857
|
+
max-width: none;
|
|
1858
|
+
min-width: 0;
|
|
1859
|
+
margin: 4px 10px;
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
/* Reset button as menu row */
|
|
1863
|
+
.ot-toolbar-nav .ot-reset-btn {
|
|
1864
|
+
border: none;
|
|
1865
|
+
border-radius: 0;
|
|
1866
|
+
background: transparent;
|
|
1867
|
+
height: auto;
|
|
1868
|
+
padding: 10px 16px;
|
|
1869
|
+
font-size: 14px;
|
|
1870
|
+
font-weight: 500;
|
|
1871
|
+
color: var(--foreground);
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
.ot-toolbar-nav .ot-reset-btn:hover {
|
|
1875
|
+
background: var(--accent);
|
|
1876
|
+
border-color: transparent;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
/* Badge as menu row */
|
|
1880
|
+
.ot-toolbar-nav .graph-badge {
|
|
1881
|
+
border: none;
|
|
1882
|
+
border-radius: 0;
|
|
1883
|
+
background: transparent;
|
|
1884
|
+
backdrop-filter: none;
|
|
1885
|
+
height: auto;
|
|
1886
|
+
padding: 10px 16px;
|
|
1887
|
+
font-size: 13px;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
/* ── Small mobile (≤ 600px): search goes back into burger ── */
|
|
1892
|
+
|
|
1893
|
+
@media (max-width: 600px) {
|
|
1894
|
+
.ot-toolbar .ot-search-tablet {
|
|
1895
|
+
display: none;
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
.ot-toolbar .ot-search-nav {
|
|
1899
|
+
display: contents;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
.ot-toolbar .ot-persistent-mobile {
|
|
1903
|
+
margin-left: auto;
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
/* ── Extra small (≤ 640px) ──────────────────── */
|
|
1908
|
+
|
|
1909
|
+
@media (max-width: 640px) {
|
|
1910
|
+
.ot-toolbar {
|
|
1911
|
+
padding: max(10px, env(safe-area-inset-top))
|
|
1912
|
+
max(12px, env(safe-area-inset-right)) 10px
|
|
1913
|
+
max(12px, env(safe-area-inset-left));
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
.ot-toolbar h1 {
|
|
1917
|
+
display: none;
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
.ot-toolbar-nav .ot-search-container {
|
|
1921
|
+
margin: 4px 8px;
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
.ot-toolbar .ot-search-btn {
|
|
1925
|
+
width: 32px;
|
|
1926
|
+
height: 32px;
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
.ot-toolbar .ot-hops-input {
|
|
1930
|
+
width: 40px;
|
|
1931
|
+
height: 28px;
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
/*
|
|
1935
|
+
* Copyright 2026 OpenTrace Contributors
|
|
1936
|
+
*
|
|
1937
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1938
|
+
* you may not use this file except in compliance with the License.
|
|
1939
|
+
* You may obtain a copy of the License at
|
|
1940
|
+
*
|
|
1941
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1942
|
+
*
|
|
1943
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1944
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1945
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1946
|
+
* See the License for the specific language governing permissions and
|
|
1947
|
+
* limitations under the License.
|
|
1948
|
+
*/
|
|
1949
|
+
|
|
1507
1950
|
/* Discover Panel — directory tree view */
|
|
1508
1951
|
|
|
1509
1952
|
.discover-panel {
|
|
@@ -7799,7 +7799,7 @@ function GraphBadge({
|
|
|
7799
7799
|
totalNodes,
|
|
7800
7800
|
")"
|
|
7801
7801
|
] }),
|
|
7802
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "nodes" }),
|
|
7802
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "graph-badge-label", children: "nodes" }),
|
|
7803
7803
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "graph-badge-sep", children: "·" }),
|
|
7804
7804
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "graph-badge-rendered", children: edgeCount }),
|
|
7805
7805
|
totalEdges != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "graph-badge-total", children: [
|
|
@@ -7807,7 +7807,7 @@ function GraphBadge({
|
|
|
7807
7807
|
totalEdges,
|
|
7808
7808
|
")"
|
|
7809
7809
|
] }),
|
|
7810
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "edges" })
|
|
7810
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "graph-badge-label", children: "edges" })
|
|
7811
7811
|
] });
|
|
7812
7812
|
}
|
|
7813
7813
|
const DEFAULT_MAX_VISIBLE = 5;
|
|
@@ -7877,6 +7877,198 @@ function GraphLegend({
|
|
|
7877
7877
|
] })
|
|
7878
7878
|
] });
|
|
7879
7879
|
}
|
|
7880
|
+
function GraphToolbar({
|
|
7881
|
+
logo,
|
|
7882
|
+
searchQuery,
|
|
7883
|
+
onSearchQueryChange,
|
|
7884
|
+
onSearch,
|
|
7885
|
+
onReset,
|
|
7886
|
+
searchDisabled,
|
|
7887
|
+
showResetButton,
|
|
7888
|
+
hops,
|
|
7889
|
+
onHopsChange,
|
|
7890
|
+
maxHops = 5,
|
|
7891
|
+
nodeCount,
|
|
7892
|
+
edgeCount,
|
|
7893
|
+
totalNodes,
|
|
7894
|
+
totalEdges,
|
|
7895
|
+
mobilePanelTabs,
|
|
7896
|
+
onMobilePanelTab,
|
|
7897
|
+
actions,
|
|
7898
|
+
persistentActions,
|
|
7899
|
+
className
|
|
7900
|
+
}) {
|
|
7901
|
+
const [menuOpen, setMenuOpen] = t.useState(false);
|
|
7902
|
+
const navRef = t.useRef(null);
|
|
7903
|
+
const burgerRef = t.useRef(null);
|
|
7904
|
+
t.useEffect(() => {
|
|
7905
|
+
if (!menuOpen) return;
|
|
7906
|
+
const onClickOutside = (e2) => {
|
|
7907
|
+
if (navRef.current?.contains(e2.target)) return;
|
|
7908
|
+
if (burgerRef.current?.contains(e2.target)) return;
|
|
7909
|
+
setMenuOpen(false);
|
|
7910
|
+
};
|
|
7911
|
+
const onEscape = (e2) => {
|
|
7912
|
+
if (e2.key === "Escape") setMenuOpen(false);
|
|
7913
|
+
};
|
|
7914
|
+
document.addEventListener("mousedown", onClickOutside);
|
|
7915
|
+
document.addEventListener("keydown", onEscape);
|
|
7916
|
+
return () => {
|
|
7917
|
+
document.removeEventListener("mousedown", onClickOutside);
|
|
7918
|
+
document.removeEventListener("keydown", onEscape);
|
|
7919
|
+
};
|
|
7920
|
+
}, [menuOpen]);
|
|
7921
|
+
const handleNavClick = t.useCallback((e2) => {
|
|
7922
|
+
const target = e2.target;
|
|
7923
|
+
const clickable = target.closest("button, a");
|
|
7924
|
+
if (clickable && !clickable.classList.contains("ot-clear-search") && !clickable.classList.contains("ot-search-btn")) {
|
|
7925
|
+
setMenuOpen(false);
|
|
7926
|
+
}
|
|
7927
|
+
}, []);
|
|
7928
|
+
const visibleTabs = mobilePanelTabs?.filter((t2) => t2.visible !== false);
|
|
7929
|
+
const searchMarkup = (id) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ot-search-container", children: [
|
|
7930
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7931
|
+
"input",
|
|
7932
|
+
{
|
|
7933
|
+
type: "text",
|
|
7934
|
+
placeholder: "Search nodes...",
|
|
7935
|
+
value: searchQuery,
|
|
7936
|
+
onChange: (e2) => onSearchQueryChange(e2.target.value),
|
|
7937
|
+
onKeyDown: (e2) => e2.key === "Enter" && onSearch(),
|
|
7938
|
+
className: "ot-search-input"
|
|
7939
|
+
}
|
|
7940
|
+
),
|
|
7941
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ot-search-params", children: [
|
|
7942
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `ot-hops-input-${id}`, children: "Hops:" }),
|
|
7943
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7944
|
+
"input",
|
|
7945
|
+
{
|
|
7946
|
+
id: `ot-hops-input-${id}`,
|
|
7947
|
+
type: "number",
|
|
7948
|
+
min: "0",
|
|
7949
|
+
max: maxHops,
|
|
7950
|
+
value: hops,
|
|
7951
|
+
onChange: (e2) => onHopsChange(
|
|
7952
|
+
Math.min(maxHops, Math.max(0, parseInt(e2.target.value) || 0))
|
|
7953
|
+
),
|
|
7954
|
+
className: "ot-hops-input",
|
|
7955
|
+
title: `Number of connection hops to include (max ${maxHops})`
|
|
7956
|
+
}
|
|
7957
|
+
)
|
|
7958
|
+
] }),
|
|
7959
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ot-search-actions", children: [
|
|
7960
|
+
searchQuery && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7961
|
+
"button",
|
|
7962
|
+
{
|
|
7963
|
+
className: "ot-clear-search",
|
|
7964
|
+
onClick: onReset,
|
|
7965
|
+
title: "Clear search",
|
|
7966
|
+
children: "×"
|
|
7967
|
+
}
|
|
7968
|
+
),
|
|
7969
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7970
|
+
"button",
|
|
7971
|
+
{
|
|
7972
|
+
className: "ot-search-btn",
|
|
7973
|
+
onClick: onSearch,
|
|
7974
|
+
title: "Query API and rerender",
|
|
7975
|
+
disabled: searchDisabled,
|
|
7976
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7977
|
+
"svg",
|
|
7978
|
+
{
|
|
7979
|
+
width: "14",
|
|
7980
|
+
height: "14",
|
|
7981
|
+
viewBox: "0 0 24 24",
|
|
7982
|
+
fill: "none",
|
|
7983
|
+
stroke: "currentColor",
|
|
7984
|
+
strokeWidth: "2.5",
|
|
7985
|
+
strokeLinecap: "round",
|
|
7986
|
+
strokeLinejoin: "round",
|
|
7987
|
+
children: [
|
|
7988
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "8" }),
|
|
7989
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
|
|
7990
|
+
]
|
|
7991
|
+
}
|
|
7992
|
+
)
|
|
7993
|
+
}
|
|
7994
|
+
)
|
|
7995
|
+
] })
|
|
7996
|
+
] });
|
|
7997
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: `ot-toolbar${className ? ` ${className}` : ""}`, children: [
|
|
7998
|
+
logo,
|
|
7999
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "ot-search-tablet", children: searchMarkup("tablet") }),
|
|
8000
|
+
persistentActions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ot-persistent-mobile", children: persistentActions }),
|
|
8001
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8002
|
+
"button",
|
|
8003
|
+
{
|
|
8004
|
+
type: "button",
|
|
8005
|
+
className: "ot-burger-btn",
|
|
8006
|
+
ref: burgerRef,
|
|
8007
|
+
onClick: () => setMenuOpen((v2) => !v2),
|
|
8008
|
+
"aria-label": "Toggle menu",
|
|
8009
|
+
"aria-expanded": menuOpen,
|
|
8010
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8011
|
+
"svg",
|
|
8012
|
+
{
|
|
8013
|
+
width: "22",
|
|
8014
|
+
height: "22",
|
|
8015
|
+
viewBox: "0 0 24 24",
|
|
8016
|
+
fill: "none",
|
|
8017
|
+
stroke: "currentColor",
|
|
8018
|
+
strokeWidth: "2",
|
|
8019
|
+
strokeLinecap: "round",
|
|
8020
|
+
strokeLinejoin: "round",
|
|
8021
|
+
children: menuOpen ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8022
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
8023
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
8024
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8025
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
|
|
8026
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
|
|
8027
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
|
|
8028
|
+
] })
|
|
8029
|
+
}
|
|
8030
|
+
)
|
|
8031
|
+
}
|
|
8032
|
+
),
|
|
8033
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
8034
|
+
"nav",
|
|
8035
|
+
{
|
|
8036
|
+
className: `ot-toolbar-nav${menuOpen ? " open" : ""}`,
|
|
8037
|
+
ref: navRef,
|
|
8038
|
+
onClick: handleNavClick,
|
|
8039
|
+
children: [
|
|
8040
|
+
visibleTabs?.map((tab) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8041
|
+
"button",
|
|
8042
|
+
{
|
|
8043
|
+
type: "button",
|
|
8044
|
+
className: "ot-mobile-panel-btn",
|
|
8045
|
+
onClick: () => onMobilePanelTab?.(tab.key),
|
|
8046
|
+
children: [
|
|
8047
|
+
tab.icon,
|
|
8048
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ot-menu-label", children: tab.label })
|
|
8049
|
+
]
|
|
8050
|
+
},
|
|
8051
|
+
tab.key
|
|
8052
|
+
)),
|
|
8053
|
+
visibleTabs && visibleTabs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ot-menu-divider" }),
|
|
8054
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "ot-search-nav", children: searchMarkup("nav") }),
|
|
8055
|
+
showResetButton && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "ot-reset-btn", onClick: onReset, children: "Show All" }),
|
|
8056
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8057
|
+
GraphBadge,
|
|
8058
|
+
{
|
|
8059
|
+
nodeCount,
|
|
8060
|
+
edgeCount,
|
|
8061
|
+
totalNodes,
|
|
8062
|
+
totalEdges
|
|
8063
|
+
}
|
|
8064
|
+
),
|
|
8065
|
+
persistentActions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ot-persistent-desktop", children: persistentActions }),
|
|
8066
|
+
actions
|
|
8067
|
+
]
|
|
8068
|
+
}
|
|
8069
|
+
)
|
|
8070
|
+
] });
|
|
8071
|
+
}
|
|
7880
8072
|
const q = typeof window < "u" ? t.useLayoutEffect : t.useEffect;
|
|
7881
8073
|
function ie(e2) {
|
|
7882
8074
|
if (e2 !== void 0)
|
|
@@ -8805,6 +8997,7 @@ exports.Graph = GraphCanvas;
|
|
|
8805
8997
|
exports.GraphBadge = GraphBadge;
|
|
8806
8998
|
exports.GraphCanvas = GraphCanvas;
|
|
8807
8999
|
exports.GraphLegend = GraphLegend;
|
|
9000
|
+
exports.GraphToolbar = GraphToolbar;
|
|
8808
9001
|
exports.LABEL_COLOR = LABEL_COLOR;
|
|
8809
9002
|
exports.LABEL_FONT = LABEL_FONT;
|
|
8810
9003
|
exports.LABEL_RENDERED_SIZE_THRESHOLD = LABEL_RENDERED_SIZE_THRESHOLD;
|