dev-api-ui 0.1.7
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/README.md +36 -0
- package/package.json +40 -0
- package/ui/ThemeProvider.tsx +16 -0
- package/ui/components/ArticlePage.tsx +673 -0
- package/ui/components/AuthPage.tsx +109 -0
- package/ui/components/Callout.tsx +79 -0
- package/ui/components/Chart.tsx +100 -0
- package/ui/components/CodeTabs.tsx +145 -0
- package/ui/components/ComparePage.tsx +364 -0
- package/ui/components/DashboardPage.tsx +773 -0
- package/ui/components/DocsNav.tsx +80 -0
- package/ui/components/Footer.tsx +136 -0
- package/ui/components/HubPage.tsx +529 -0
- package/ui/components/Modal.tsx +412 -0
- package/ui/components/Nav.tsx +162 -0
- package/ui/components/OnThisPage.tsx +56 -0
- package/ui/components/ParamsTable.tsx +86 -0
- package/ui/components/RangeBar.tsx +68 -0
- package/ui/components/SeriesChart.tsx +218 -0
- package/ui/components/SeriesPage.tsx +461 -0
- package/ui/components/StatusMark.tsx +48 -0
- package/ui/components/publictrades/ExternalLink.tsx +37 -0
- package/ui/components/publictrades/FactsCard.tsx +40 -0
- package/ui/components/publictrades/LedgerFooter.tsx +22 -0
- package/ui/components/publictrades/LedgerNav.tsx +78 -0
- package/ui/components/publictrades/Mark.tsx +40 -0
- package/ui/components/publictrades/SourceBlock.tsx +91 -0
- package/ui/components/publictrades/Tape.tsx +164 -0
- package/ui/components/publictrades/ThreeStamps.tsx +47 -0
- package/ui/components/publictrades/types.ts +19 -0
- package/ui/data/series.ts +851 -0
- package/ui/index.ts +50 -0
- package/ui/publictrades.ts +16 -0
- package/ui/themes.css +81 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
interface NavItem {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface NavSection {
|
|
10
|
+
title: string;
|
|
11
|
+
items: NavItem[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface DocsNavProps {
|
|
15
|
+
sections: NavSection[];
|
|
16
|
+
active: string;
|
|
17
|
+
onSelect: (id: string) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default function DocsNav({ sections, active, onSelect }: DocsNavProps) {
|
|
21
|
+
return (
|
|
22
|
+
<aside
|
|
23
|
+
style={{
|
|
24
|
+
position: 'sticky',
|
|
25
|
+
top: 57,
|
|
26
|
+
alignSelf: 'start',
|
|
27
|
+
height: 'calc(100vh - 57px)',
|
|
28
|
+
overflowY: 'auto',
|
|
29
|
+
borderRight: '0.5px solid var(--hairline)',
|
|
30
|
+
padding: '26px 22px 40px',
|
|
31
|
+
}}
|
|
32
|
+
>
|
|
33
|
+
{sections.map((s) => (
|
|
34
|
+
<div key={s.title} style={{ marginBottom: 22 }}>
|
|
35
|
+
<div
|
|
36
|
+
style={{
|
|
37
|
+
fontSize: 11,
|
|
38
|
+
fontWeight: 600,
|
|
39
|
+
textTransform: 'uppercase',
|
|
40
|
+
letterSpacing: '.07em',
|
|
41
|
+
color: 'var(--tertiary)',
|
|
42
|
+
marginBottom: 9,
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
{s.title}
|
|
46
|
+
</div>
|
|
47
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
48
|
+
{s.items.map((it) => {
|
|
49
|
+
const isActive = active === it.id;
|
|
50
|
+
return (
|
|
51
|
+
<a
|
|
52
|
+
key={it.id}
|
|
53
|
+
href={`#${it.id}`}
|
|
54
|
+
onClick={(e) => {
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
onSelect(it.id);
|
|
57
|
+
const el = document.getElementById(it.id);
|
|
58
|
+
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
59
|
+
}}
|
|
60
|
+
aria-current={isActive ? 'page' : undefined}
|
|
61
|
+
style={{
|
|
62
|
+
fontSize: 14,
|
|
63
|
+
padding: '5px 10px',
|
|
64
|
+
borderRadius: 4,
|
|
65
|
+
textDecoration: 'none',
|
|
66
|
+
color: isActive ? 'var(--ink)' : 'var(--secondary)',
|
|
67
|
+
background: isActive ? '#F2F2EF' : 'transparent',
|
|
68
|
+
borderLeft: `2px solid ${isActive ? 'var(--accent)' : 'transparent'}`,
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
{it.label}
|
|
72
|
+
</a>
|
|
73
|
+
);
|
|
74
|
+
})}
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
))}
|
|
78
|
+
</aside>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import Link from 'next/link';
|
|
2
|
+
|
|
3
|
+
export interface FooterLink {
|
|
4
|
+
label: string;
|
|
5
|
+
href: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface FooterProps {
|
|
9
|
+
wordmark?: string;
|
|
10
|
+
tagline?: string;
|
|
11
|
+
byline?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Links rendered in the footer "Legal" column. Defaults to the universal
|
|
14
|
+
* /terms + /privacy routes every product ships. Pass an explicit list to
|
|
15
|
+
* override (e.g. add /privacy/subprocessors or an SLA page).
|
|
16
|
+
*/
|
|
17
|
+
legalLinks?: FooterLink[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default function Footer({
|
|
21
|
+
wordmark = 'Console',
|
|
22
|
+
tagline = 'the data API',
|
|
23
|
+
byline = '',
|
|
24
|
+
legalLinks = [
|
|
25
|
+
{ label: 'Terms', href: '/terms' },
|
|
26
|
+
{ label: 'Privacy', href: '/privacy' },
|
|
27
|
+
],
|
|
28
|
+
}: FooterProps = {}) {
|
|
29
|
+
return (
|
|
30
|
+
<footer
|
|
31
|
+
style={{
|
|
32
|
+
borderTop: '0.5px solid var(--hairline)',
|
|
33
|
+
padding: '40px 0 56px',
|
|
34
|
+
marginTop: 62,
|
|
35
|
+
background: 'var(--surface)',
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
<div
|
|
39
|
+
style={{
|
|
40
|
+
maxWidth: 1100,
|
|
41
|
+
margin: '0 auto',
|
|
42
|
+
padding: '0 32px',
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
{/* Upper block: wordmark + link columns */}
|
|
46
|
+
<div
|
|
47
|
+
style={{
|
|
48
|
+
display: 'flex',
|
|
49
|
+
justifyContent: 'space-between',
|
|
50
|
+
gap: 30,
|
|
51
|
+
flexWrap: 'wrap',
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
{/* Wordmark */}
|
|
55
|
+
<div
|
|
56
|
+
style={{
|
|
57
|
+
display: 'flex',
|
|
58
|
+
alignItems: 'center',
|
|
59
|
+
gap: 9,
|
|
60
|
+
fontFamily: 'var(--head)',
|
|
61
|
+
fontWeight: 600,
|
|
62
|
+
fontSize: 15,
|
|
63
|
+
letterSpacing: '-0.01em',
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<span
|
|
67
|
+
style={{
|
|
68
|
+
width: 8,
|
|
69
|
+
height: 8,
|
|
70
|
+
background: 'var(--accent)',
|
|
71
|
+
transform: 'rotate(45deg)',
|
|
72
|
+
display: 'inline-block',
|
|
73
|
+
}}
|
|
74
|
+
/>
|
|
75
|
+
{wordmark}
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
{/* Link columns */}
|
|
79
|
+
<div style={{ display: 'flex', gap: 46, flexWrap: 'wrap' }}>
|
|
80
|
+
<div style={{ display: 'grid', gap: 8, fontSize: 13, color: 'var(--secondary)' }}>
|
|
81
|
+
<span style={{ color: 'var(--tertiary)', fontSize: 11, textTransform: 'uppercase', letterSpacing: '.08em', fontWeight: 600 }}>Product</span>
|
|
82
|
+
<Link href="/fx" style={{ color: 'var(--secondary)', textDecoration: 'none' }}>Data</Link>
|
|
83
|
+
<Link href="/docs" style={{ color: 'var(--secondary)', textDecoration: 'none' }}>Docs</Link>
|
|
84
|
+
<Link href="/pricing" style={{ color: 'var(--secondary)', textDecoration: 'none' }}>Pricing</Link>
|
|
85
|
+
<Link href="/status" style={{ color: 'var(--secondary)', textDecoration: 'none' }}>Status</Link>
|
|
86
|
+
</div>
|
|
87
|
+
<div style={{ display: 'grid', gap: 8, fontSize: 13, color: 'var(--secondary)' }}>
|
|
88
|
+
<span style={{ color: 'var(--tertiary)', fontSize: 11, textTransform: 'uppercase', letterSpacing: '.08em', fontWeight: 600 }}>Company</span>
|
|
89
|
+
<a href="#" style={{ color: 'var(--secondary)', textDecoration: 'none' }}>About</a>
|
|
90
|
+
<a href="#" style={{ color: 'var(--secondary)', textDecoration: 'none' }}>Customers</a>
|
|
91
|
+
<a href="#" style={{ color: 'var(--secondary)', textDecoration: 'none' }}>Enterprise</a>
|
|
92
|
+
</div>
|
|
93
|
+
<div style={{ display: 'grid', gap: 8, fontSize: 13, color: 'var(--secondary)' }}>
|
|
94
|
+
<span style={{ color: 'var(--tertiary)', fontSize: 11, textTransform: 'uppercase', letterSpacing: '.08em', fontWeight: 600 }}>Legal</span>
|
|
95
|
+
{legalLinks.map((l) => (
|
|
96
|
+
<Link key={l.href} href={l.href} style={{ color: 'var(--secondary)', textDecoration: 'none' }}>{l.label}</Link>
|
|
97
|
+
))}
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
{/* 0.5px divider */}
|
|
103
|
+
<div
|
|
104
|
+
style={{
|
|
105
|
+
borderTop: '0.5px solid var(--hairline)',
|
|
106
|
+
marginTop: 30,
|
|
107
|
+
paddingTop: 18,
|
|
108
|
+
fontSize: 12,
|
|
109
|
+
color: 'var(--tertiary)',
|
|
110
|
+
display: 'flex',
|
|
111
|
+
justifyContent: 'space-between',
|
|
112
|
+
gap: 16,
|
|
113
|
+
flexWrap: 'wrap',
|
|
114
|
+
}}
|
|
115
|
+
>
|
|
116
|
+
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
|
|
117
|
+
<span
|
|
118
|
+
style={{
|
|
119
|
+
width: 8,
|
|
120
|
+
height: 8,
|
|
121
|
+
background: 'var(--accent)',
|
|
122
|
+
transform: 'rotate(45deg)',
|
|
123
|
+
display: 'inline-block',
|
|
124
|
+
}}
|
|
125
|
+
/>
|
|
126
|
+
{wordmark} · {tagline}{byline ? ` · ${byline}` : ''}
|
|
127
|
+
</span>
|
|
128
|
+
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 12 }}>
|
|
129
|
+
<a href="https://www.tradingview.com" target="_blank" rel="noreferrer" style={{ color: 'var(--tertiary)', textDecoration: 'none' }}>Charts by TradingView</a>
|
|
130
|
+
<span>© 2026</span>
|
|
131
|
+
</span>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</footer>
|
|
135
|
+
);
|
|
136
|
+
}
|