@xenide-io/the-old-ui-theme 0.2.6 → 0.2.9
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/chunk-SHF57J7U.mjs +2910 -0
- package/dist/index-CmS6hcUk.d.mts +753 -0
- package/dist/index-CmS6hcUk.d.ts +753 -0
- package/dist/index.d.mts +5 -755
- package/dist/index.d.ts +5 -755
- package/dist/index.js +43 -23
- package/dist/index.mjs +252 -2846
- package/dist/ui.d.mts +3 -0
- package/dist/ui.d.ts +3 -0
- package/dist/ui.js +2946 -0
- package/dist/ui.mjs +139 -0
- package/package.json +11 -3
- package/src/components/charts/index.ts +8 -0
- package/src/components/charts/ph-insight-charts.tsx +162 -0
- package/src/components/dashboard/DashboardFiltersBar.tsx +19 -0
- package/src/components/dashboard/DashboardGrid.tsx +23 -0
- package/src/components/dashboard/DashboardInsightPlaceholder.tsx +37 -0
- package/src/components/dashboard/DashboardKpiCard.tsx +25 -0
- package/src/components/dashboard/DashboardToolbar.tsx +23 -0
- package/src/components/dashboard/DashboardWell.tsx +10 -0
- package/src/components/dashboard/InsightMiniCard.tsx +26 -0
- package/src/components/dashboard/InsightShell.tsx +37 -0
- package/src/components/dashboard/InsightShellHeader.tsx +22 -0
- package/src/components/dashboard/MiniTrendBars.tsx +51 -0
- package/src/components/dashboard/index.ts +31 -0
- package/src/components/dashboard/types.ts +9 -0
- package/src/components/icons/IconBase.tsx +39 -0
- package/src/components/icons/createIconBase.tsx +27 -0
- package/src/components/icons/icons.tsx +367 -0
- package/src/components/icons/index.ts +3 -0
- package/src/components/sections/AccordionShowcase.tsx +45 -0
- package/src/components/sections/AlertShowcase.tsx +39 -0
- package/src/components/sections/AvatarShowcase.tsx +80 -0
- package/src/components/sections/BadgeShowcase.tsx +65 -0
- package/src/components/sections/ButtonShowcase.tsx +312 -0
- package/src/components/sections/CalendarShowcase.tsx +35 -0
- package/src/components/sections/CardShowcase.tsx +143 -0
- package/src/components/sections/ChartShowcase.tsx +190 -0
- package/src/components/sections/CodeMockupShowcase.tsx +56 -0
- package/src/components/sections/ColorPalette.tsx +117 -0
- package/src/components/sections/CommandPaletteShowcase.tsx +48 -0
- package/src/components/sections/CountdownShowcase.tsx +43 -0
- package/src/components/sections/DashboardShowcase.tsx +191 -0
- package/src/components/sections/DiffShowcase.tsx +70 -0
- package/src/components/sections/DrawerShowcase.tsx +97 -0
- package/src/components/sections/DropdownShowcase.tsx +100 -0
- package/src/components/sections/EmptyStateShowcase.tsx +50 -0
- package/src/components/sections/FilterChipsShowcase.tsx +50 -0
- package/src/components/sections/FormShowcase.tsx +126 -0
- package/src/components/sections/HoverCardShowcase.tsx +50 -0
- package/src/components/sections/IconShowcase.tsx +247 -0
- package/src/components/sections/IndicatorShowcase.tsx +52 -0
- package/src/components/sections/KbdShowcase.tsx +31 -0
- package/src/components/sections/ModalShowcase.tsx +210 -0
- package/src/components/sections/NavigationShowcase.tsx +199 -0
- package/src/components/sections/ProgressShowcase.tsx +85 -0
- package/src/components/sections/SegmentedControlShowcase.tsx +49 -0
- package/src/components/sections/SetupThemeShowcase.tsx +262 -0
- package/src/components/sections/StackShowcase.tsx +33 -0
- package/src/components/sections/StatShowcase.tsx +129 -0
- package/src/components/sections/StepperShowcase.tsx +37 -0
- package/src/components/sections/SwapShowcase.tsx +91 -0
- package/src/components/sections/TabShowcase.tsx +84 -0
- package/src/components/sections/TableShowcase.tsx +140 -0
- package/src/components/sections/TimelineShowcase.tsx +83 -0
- package/src/components/sections/ToastShowcase.tsx +108 -0
- package/src/components/sections/TooltipShowcase.tsx +44 -0
- package/src/components/sections/UtilityShowcase.tsx +81 -0
- package/src/components/ui/Accordion.tsx +77 -0
- package/src/components/ui/Alert.tsx +68 -0
- package/src/components/ui/Avatar.tsx +97 -0
- package/src/components/ui/Badge.tsx +55 -0
- package/src/components/ui/Button.tsx +110 -0
- package/src/components/ui/ButtonChrome.tsx +20 -0
- package/src/components/ui/Calendar.tsx +116 -0
- package/src/components/ui/Card.tsx +60 -0
- package/src/components/ui/ChatBubble.tsx +71 -0
- package/src/components/ui/CodeBlock.tsx +48 -0
- package/src/components/ui/CollapsibleSection.tsx +49 -0
- package/src/components/ui/CommandPalette.tsx +137 -0
- package/src/components/ui/ComponentDocs.tsx +52 -0
- package/src/components/ui/Drawer.tsx +71 -0
- package/src/components/ui/DropdownMenu.tsx +138 -0
- package/src/components/ui/EmptyState.tsx +33 -0
- package/src/components/ui/FilterChips.tsx +50 -0
- package/src/components/ui/HoverCard.tsx +36 -0
- package/src/components/ui/Indicator.tsx +61 -0
- package/src/components/ui/Input.tsx +359 -0
- package/src/components/ui/Kbd.tsx +38 -0
- package/src/components/ui/Modal.tsx +75 -0
- package/src/components/ui/Navigation.tsx +94 -0
- package/src/components/ui/Panel.tsx +18 -0
- package/src/components/ui/Progress.tsx +59 -0
- package/src/components/ui/Rating.tsx +65 -0
- package/src/components/ui/SearchInput.tsx +106 -0
- package/src/components/ui/SegmentedControl.tsx +44 -0
- package/src/components/ui/ShowcaseWrapper.tsx +136 -0
- package/src/components/ui/Stat.tsx +39 -0
- package/src/components/ui/Stepper.tsx +75 -0
- package/src/components/ui/Table.tsx +55 -0
- package/src/components/ui/Tabs.tsx +53 -0
- package/src/components/ui/Terminal.tsx +54 -0
- package/src/components/ui/ThemeDomSync.tsx +17 -0
- package/src/components/ui/ThemeManager.tsx +18 -0
- package/src/components/ui/ThemeSwitcher.tsx +46 -0
- package/src/components/ui/Timeline.tsx +60 -0
- package/src/components/ui/Toast.tsx +70 -0
- package/src/components/ui/Typography.tsx +129 -0
- package/src/components/ui/index.ts +92 -0
- package/src/styles/themes.css +118 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HogTrendLineChart,
|
|
3
|
+
InsightDoughnutChart,
|
|
4
|
+
InsightHorizontalBarChart,
|
|
5
|
+
InsightPolarAreaChart,
|
|
6
|
+
InsightStackedBarChart,
|
|
7
|
+
InsightVerticalBarChart,
|
|
8
|
+
} from "@/components/charts";
|
|
9
|
+
import { DashboardWell, InsightShell, InsightShellHeader } from "@/components/dashboard";
|
|
10
|
+
import { ShowcaseWrapper } from "@/components/ui";
|
|
11
|
+
|
|
12
|
+
export default function ChartShowcase() {
|
|
13
|
+
const code = `import { HogTrendLineChart, InsightDoughnutChart, InsightHorizontalBarChart, InsightPolarAreaChart, InsightStackedBarChart, InsightVerticalBarChart } from "the-old-ui";
|
|
14
|
+
import { DashboardWell, InsightShell, InsightShellHeader } from "the-old-ui";
|
|
15
|
+
|
|
16
|
+
<DashboardWell>
|
|
17
|
+
<div className="grid gap-6 lg:grid-cols-2">
|
|
18
|
+
<InsightShell className="min-h-0">
|
|
19
|
+
<InsightShellHeader
|
|
20
|
+
title="Trends (hog-charts model · canvas + d3-scale)"
|
|
21
|
+
subtitle={
|
|
22
|
+
<>
|
|
23
|
+
Same <code className="ph-kbd">Series</code> shape as PostHog (<code className="ph-kbd">stroke.pattern</code>,
|
|
24
|
+
<code className="ph-kbd">fill.opacity</code>), 2 px round-capped strokes, horizontal grid, dashed
|
|
25
|
+
crosshair, multi-series hover ring.
|
|
26
|
+
</>
|
|
27
|
+
}
|
|
28
|
+
/>
|
|
29
|
+
<HogTrendLineChart />
|
|
30
|
+
</InsightShell>
|
|
31
|
+
|
|
32
|
+
<InsightShell className="min-h-0">
|
|
33
|
+
<InsightShellHeader
|
|
34
|
+
title="Vertical bars (Chart.js)"
|
|
35
|
+
subtitle={
|
|
36
|
+
<>
|
|
37
|
+
Bar charts in PostHog's UI are also built on <code className="ph-kbd">TimeSeriesBarChart</code> /
|
|
38
|
+
<code className="ph-kbd">BarChart</code> in hog-charts; this tile uses Chart.js with the same semantic
|
|
39
|
+
<code className="ph-kbd">--ph-data-*</code> colours.
|
|
40
|
+
</>
|
|
41
|
+
}
|
|
42
|
+
/>
|
|
43
|
+
<InsightVerticalBarChart />
|
|
44
|
+
</InsightShell>
|
|
45
|
+
|
|
46
|
+
<InsightShell className="min-h-0 lg:col-span-2">
|
|
47
|
+
<InsightShellHeader
|
|
48
|
+
title="Horizontal bar (Chart.js)"
|
|
49
|
+
subtitle={
|
|
50
|
+
<>
|
|
51
|
+
<code className="ph-kbd">indexAxis: "y"</code> mirrors long-label breakdowns (URLs, flags, cohorts).
|
|
52
|
+
</>
|
|
53
|
+
}
|
|
54
|
+
/>
|
|
55
|
+
<InsightHorizontalBarChart />
|
|
56
|
+
</InsightShell>
|
|
57
|
+
|
|
58
|
+
<InsightShell className="min-h-0 lg:col-span-2">
|
|
59
|
+
<InsightShellHeader
|
|
60
|
+
title="Stacked breakdown (Chart.js)"
|
|
61
|
+
subtitle={
|
|
62
|
+
<>
|
|
63
|
+
Multiple datasets with <code className="ph-kbd">stacked: true</code> — analogous to multi-series bar
|
|
64
|
+
layouts in insights.
|
|
65
|
+
</>
|
|
66
|
+
}
|
|
67
|
+
/>
|
|
68
|
+
<InsightStackedBarChart />
|
|
69
|
+
</InsightShell>
|
|
70
|
+
|
|
71
|
+
<InsightShell className="min-h-0">
|
|
72
|
+
<InsightShellHeader
|
|
73
|
+
title="Doughnut (Chart.js)"
|
|
74
|
+
subtitle={
|
|
75
|
+
<>
|
|
76
|
+
<code className="ph-kbd">ArcElement</code> + <code className="ph-kbd">cutout</code> for donut slices;
|
|
77
|
+
legend and tooltip use the same CSS-variable palette.
|
|
78
|
+
</>
|
|
79
|
+
}
|
|
80
|
+
/>
|
|
81
|
+
<InsightDoughnutChart />
|
|
82
|
+
</InsightShell>
|
|
83
|
+
|
|
84
|
+
<InsightShell className="min-h-0">
|
|
85
|
+
<InsightShellHeader
|
|
86
|
+
title="Polar area (Chart.js)"
|
|
87
|
+
subtitle={
|
|
88
|
+
<>
|
|
89
|
+
<code className="ph-kbd">RadialLinearScale</code> for spoke grid lines; useful for compact multi-metric
|
|
90
|
+
comparisons.
|
|
91
|
+
</>
|
|
92
|
+
}
|
|
93
|
+
/>
|
|
94
|
+
<InsightPolarAreaChart />
|
|
95
|
+
</InsightShell>
|
|
96
|
+
</div>
|
|
97
|
+
</DashboardWell>`;
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<ShowcaseWrapper
|
|
101
|
+
title="Charts (PostHog-style)"
|
|
102
|
+
description="In the open-source PostHog app, most product-analytics trend lines and areas are drawn with hog-charts — Canvas 2D plus D3 scales. Chart.js remains for some chart types."
|
|
103
|
+
code={code}
|
|
104
|
+
filename="ChartExample.tsx"
|
|
105
|
+
>
|
|
106
|
+
<DashboardWell>
|
|
107
|
+
<div className="grid gap-6 lg:grid-cols-2">
|
|
108
|
+
<InsightShell className="min-h-0">
|
|
109
|
+
<InsightShellHeader
|
|
110
|
+
title="Trends (hog-charts model · canvas + d3-scale)"
|
|
111
|
+
subtitle={
|
|
112
|
+
<>
|
|
113
|
+
Same <code className="ph-kbd">Series</code> shape as PostHog (<code className="ph-kbd">stroke.pattern</code>,
|
|
114
|
+
<code className="ph-kbd">fill.opacity</code>), 2 px round-capped strokes, horizontal grid, dashed
|
|
115
|
+
crosshair, multi-series hover ring.
|
|
116
|
+
</>
|
|
117
|
+
}
|
|
118
|
+
/>
|
|
119
|
+
<HogTrendLineChart />
|
|
120
|
+
</InsightShell>
|
|
121
|
+
|
|
122
|
+
<InsightShell className="min-h-0">
|
|
123
|
+
<InsightShellHeader
|
|
124
|
+
title="Vertical bars (Chart.js)"
|
|
125
|
+
subtitle={
|
|
126
|
+
<>
|
|
127
|
+
Bar charts in PostHog's UI are also built on <code className="ph-kbd">TimeSeriesBarChart</code> /
|
|
128
|
+
<code className="ph-kbd">BarChart</code> in hog-charts; this tile uses Chart.js with the same semantic
|
|
129
|
+
<code className="ph-kbd">--ph-data-*</code> colours.
|
|
130
|
+
</>
|
|
131
|
+
}
|
|
132
|
+
/>
|
|
133
|
+
<InsightVerticalBarChart />
|
|
134
|
+
</InsightShell>
|
|
135
|
+
|
|
136
|
+
<InsightShell className="min-h-0 lg:col-span-2">
|
|
137
|
+
<InsightShellHeader
|
|
138
|
+
title="Horizontal bar (Chart.js)"
|
|
139
|
+
subtitle={
|
|
140
|
+
<>
|
|
141
|
+
<code className="ph-kbd">indexAxis: "y"</code> mirrors long-label breakdowns (URLs, flags, cohorts).
|
|
142
|
+
</>
|
|
143
|
+
}
|
|
144
|
+
/>
|
|
145
|
+
<InsightHorizontalBarChart />
|
|
146
|
+
</InsightShell>
|
|
147
|
+
|
|
148
|
+
<InsightShell className="min-h-0 lg:col-span-2">
|
|
149
|
+
<InsightShellHeader
|
|
150
|
+
title="Stacked breakdown (Chart.js)"
|
|
151
|
+
subtitle={
|
|
152
|
+
<>
|
|
153
|
+
Multiple datasets with <code className="ph-kbd">stacked: true</code> — analogous to multi-series bar
|
|
154
|
+
layouts in insights.
|
|
155
|
+
</>
|
|
156
|
+
}
|
|
157
|
+
/>
|
|
158
|
+
<InsightStackedBarChart />
|
|
159
|
+
</InsightShell>
|
|
160
|
+
|
|
161
|
+
<InsightShell className="min-h-0">
|
|
162
|
+
<InsightShellHeader
|
|
163
|
+
title="Doughnut (Chart.js)"
|
|
164
|
+
subtitle={
|
|
165
|
+
<>
|
|
166
|
+
<code className="ph-kbd">ArcElement</code> + <code className="ph-kbd">cutout</code> for donut slices;
|
|
167
|
+
legend and tooltip use the same CSS-variable palette.
|
|
168
|
+
</>
|
|
169
|
+
}
|
|
170
|
+
/>
|
|
171
|
+
<InsightDoughnutChart />
|
|
172
|
+
</InsightShell>
|
|
173
|
+
|
|
174
|
+
<InsightShell className="min-h-0">
|
|
175
|
+
<InsightShellHeader
|
|
176
|
+
title="Polar area (Chart.js)"
|
|
177
|
+
subtitle={
|
|
178
|
+
<>
|
|
179
|
+
<code className="ph-kbd">RadialLinearScale</code> for spoke grid lines; useful for compact multi-metric
|
|
180
|
+
comparisons.
|
|
181
|
+
</>
|
|
182
|
+
}
|
|
183
|
+
/>
|
|
184
|
+
<InsightPolarAreaChart />
|
|
185
|
+
</InsightShell>
|
|
186
|
+
</div>
|
|
187
|
+
</DashboardWell>
|
|
188
|
+
</ShowcaseWrapper>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { IconQueryEditor } from "@/components/icons";
|
|
2
|
+
import { ComponentDocs, ShowcaseWrapper, Terminal } from "@/components/ui";
|
|
3
|
+
|
|
4
|
+
export default function CodeMockupShowcase() {
|
|
5
|
+
const code = `import { Terminal } from "the-old-ui";
|
|
6
|
+
|
|
7
|
+
<Terminal
|
|
8
|
+
title="sandbox · posthog-wizard"
|
|
9
|
+
lines={[
|
|
10
|
+
{ text: "❯ bun add posthog-js", color: "text-neutral-600" },
|
|
11
|
+
{ text: "● added posthog-js@1...", color: "text-emerald-400" },
|
|
12
|
+
{ text: "❯ POSTHOG_KEY=...", color: "text-neutral-600" },
|
|
13
|
+
]}
|
|
14
|
+
/>`;
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<ShowcaseWrapper
|
|
18
|
+
title="Terminal capture"
|
|
19
|
+
description="Terminal and replay shells for documentation, demos, and embedded developer flows."
|
|
20
|
+
code={code}
|
|
21
|
+
filename="TerminalExample.tsx"
|
|
22
|
+
docs={
|
|
23
|
+
<ComponentDocs
|
|
24
|
+
rows={[
|
|
25
|
+
{ name: "title", type: "string", description: "Window title in the header." },
|
|
26
|
+
{ name: "lines", type: "Array<{ text; color? }>", description: "Terminal lines to render." },
|
|
27
|
+
{ name: "children", type: "ReactNode", description: "Custom content instead of lines." },
|
|
28
|
+
]}
|
|
29
|
+
/>
|
|
30
|
+
}
|
|
31
|
+
>
|
|
32
|
+
<div className="space-y-10">
|
|
33
|
+
<Terminal
|
|
34
|
+
title="sandbox · posthog-wizard"
|
|
35
|
+
lines={[
|
|
36
|
+
{ text: "❯ bun add posthog-js", color: "text-neutral-600" },
|
|
37
|
+
{ text: "● added posthog-js@1...", color: "text-emerald-400" },
|
|
38
|
+
{ text: "❯ POSTHOG_KEY=...", color: "text-neutral-600" },
|
|
39
|
+
]}
|
|
40
|
+
/>
|
|
41
|
+
|
|
42
|
+
<div className="rounded-xl border border-ph-border shadow-ph-md">
|
|
43
|
+
<header className="relative flex items-center justify-center border-b border-ph-border px-10 py-3 text-[11px] font-semibold text-ph-mutedtext">
|
|
44
|
+
<span className="absolute left-5 top-4 h-px w-[88%] rounded-full bg-ph-border opacity-70" />
|
|
45
|
+
Replay preview
|
|
46
|
+
</header>
|
|
47
|
+
<div className="flex flex-col items-center gap-5 bg-ph-toolbar px-6 py-14 text-ph-subtle">
|
|
48
|
+
<IconQueryEditor className="h-14 w-14 opacity-50" />
|
|
49
|
+
<p className="text-center font-semibold text-ph-ink">Session snapshot shell</p>
|
|
50
|
+
<p className="max-w-xs text-center text-xs">Mirrors bordered frame around insight embeds rather than DaisyUI mocks.</p>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</ShowcaseWrapper>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import { ShowcaseWrapper } from "@/components/ui";
|
|
3
|
+
|
|
4
|
+
const brandSurface: { label: string; token: string; style: CSSProperties; textClass: string }[] = [
|
|
5
|
+
{ label: "Brand orange", token: "--ph-accent", style: { background: "var(--ph-accent)" }, textClass: "text-white" },
|
|
6
|
+
{ label: "Brand blue", token: "--ph-blue", style: { background: "var(--ph-blue)" }, textClass: "text-white" },
|
|
7
|
+
{ label: "Purple accent", token: "--ph-purple", style: { background: "var(--ph-purple)" }, textClass: "text-white" },
|
|
8
|
+
{ label: "Canvas (3000-50)", token: "--ph-canvas", style: { background: "var(--ph-canvas)" }, textClass: "text-ph-ink ring-1 ring-inset ring-ph-border" },
|
|
9
|
+
{ label: "Muted surface", token: "--ph-muted", style: { background: "var(--ph-muted)" }, textClass: "text-ph-ink ring-1 ring-inset ring-ph-border" },
|
|
10
|
+
{ label: "White surface", token: "--ph-surface", style: { background: "var(--ph-surface)" }, textClass: "text-ph-ink ring-1 ring-inset ring-ph-border" },
|
|
11
|
+
{ label: "Border", token: "--ph-border", style: { background: "var(--ph-border)" }, textClass: "text-ph-ink" },
|
|
12
|
+
{ label: "Success", token: "--ph-success", style: { background: "var(--ph-success)" }, textClass: "text-white" },
|
|
13
|
+
{ label: "Warning", token: "--ph-warning", style: { background: "var(--ph-warning)" }, textClass: "text-white" },
|
|
14
|
+
{ label: "Danger", token: "--ph-danger", style: { background: "var(--ph-danger)" }, textClass: "text-white" },
|
|
15
|
+
{ label: "Info", token: "--ph-info", style: { background: "var(--ph-info)" }, textClass: "text-white" },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const dataSeries = [1, 2, 3, 4, 5, 6, 7].map((n) => ({
|
|
19
|
+
label: `Data ${n}`,
|
|
20
|
+
token: `--ph-data-${n}`,
|
|
21
|
+
style: { background: `var(--ph-data-${n})` } as CSSProperties,
|
|
22
|
+
textClass: "text-white",
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
const productRail = [
|
|
26
|
+
{ label: "Session replay", token: "--ph-product-session-replay", style: { background: "var(--ph-product-session-replay)" } as CSSProperties },
|
|
27
|
+
{ label: "Product analytics", token: "--ph-product-product-analytics", style: { background: "var(--ph-product-product-analytics)" } as CSSProperties },
|
|
28
|
+
{ label: "Data pipeline", token: "--ph-product-data-pipeline", style: { background: "var(--ph-product-data-pipeline)" } as CSSProperties },
|
|
29
|
+
{ label: "Feature flags", token: "--ph-product-feature-flags", style: { background: "var(--ph-product-feature-flags)" } as CSSProperties },
|
|
30
|
+
{ label: "Experiments", token: "--ph-product-experiments", style: { background: "var(--ph-product-experiments)" } as CSSProperties },
|
|
31
|
+
{ label: "Data warehouse", token: "--ph-product-data-warehouse", style: { background: "var(--ph-product-data-warehouse)" } as CSSProperties },
|
|
32
|
+
{ label: "Surveys", token: "--ph-product-surveys", style: { background: "var(--ph-product-surveys)" } as CSSProperties },
|
|
33
|
+
].map((row) => ({ ...row, textClass: "text-white" }));
|
|
34
|
+
|
|
35
|
+
function SwatchGrid({
|
|
36
|
+
title,
|
|
37
|
+
description,
|
|
38
|
+
items,
|
|
39
|
+
}: {
|
|
40
|
+
title: string;
|
|
41
|
+
description: string;
|
|
42
|
+
items: { label: string; token: string; style: CSSProperties; textClass: string }[];
|
|
43
|
+
}) {
|
|
44
|
+
return (
|
|
45
|
+
<div>
|
|
46
|
+
<h3 className="mb-1 text-xs font-semibold uppercase tracking-wider text-ph-mutedtext">{title}</h3>
|
|
47
|
+
<p className="mb-3 text-sm text-ph-subtle">{description}</p>
|
|
48
|
+
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6">
|
|
49
|
+
{items.map((c) => (
|
|
50
|
+
<div
|
|
51
|
+
key={c.token}
|
|
52
|
+
className={`rounded-[var(--ph-radius-app)] p-5 ${c.textClass}`}
|
|
53
|
+
style={{
|
|
54
|
+
...c.style,
|
|
55
|
+
boxShadow: "var(--ph-shadow-elevation-3000)",
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
<p className="text-sm font-semibold">{c.label}</p>
|
|
59
|
+
<p className="mt-1 font-mono text-[11px] opacity-90">{c.token}</p>
|
|
60
|
+
</div>
|
|
61
|
+
))}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default function ColorPalette() {
|
|
68
|
+
const code = `/* CSS variables update with the active theme */
|
|
69
|
+
|
|
70
|
+
// Brand & surfaces
|
|
71
|
+
background: var(--ph-accent); // Brand orange
|
|
72
|
+
background: var(--ph-canvas); // Canvas
|
|
73
|
+
background: var(--ph-surface); // White surface
|
|
74
|
+
border-color: var(--ph-border); // Hairline borders
|
|
75
|
+
|
|
76
|
+
// Semantic status
|
|
77
|
+
color: var(--ph-success); // Success green
|
|
78
|
+
color: var(--ph-danger); // Danger red
|
|
79
|
+
color: var(--ph-warning); // Warning amber
|
|
80
|
+
color: var(--ph-info); // Info blue
|
|
81
|
+
|
|
82
|
+
// Data series (charts)
|
|
83
|
+
background: var(--ph-data-1); // Primary
|
|
84
|
+
background: var(--ph-data-2); // Secondary
|
|
85
|
+
// ... up to ph-data-7
|
|
86
|
+
|
|
87
|
+
// Product rail
|
|
88
|
+
background: var(--ph-product-session-replay);
|
|
89
|
+
background: var(--ph-product-product-analytics);`;
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<ShowcaseWrapper
|
|
93
|
+
title="Colour tokens"
|
|
94
|
+
description="Tokens update with the Theme select in the header — surfaces, accents, chart series, and product rail colours all swap together."
|
|
95
|
+
code={code}
|
|
96
|
+
filename="Tokens.css"
|
|
97
|
+
>
|
|
98
|
+
<div className="space-y-10">
|
|
99
|
+
<SwatchGrid
|
|
100
|
+
title="Brand & surfaces"
|
|
101
|
+
description="Core UI chrome and semantic status hues."
|
|
102
|
+
items={brandSurface}
|
|
103
|
+
/>
|
|
104
|
+
<SwatchGrid
|
|
105
|
+
title="Insight data series"
|
|
106
|
+
description="Default trend / breakdown palette."
|
|
107
|
+
items={dataSeries}
|
|
108
|
+
/>
|
|
109
|
+
<SwatchGrid
|
|
110
|
+
title="Product rail"
|
|
111
|
+
description="Saturated nav / marketing tiles."
|
|
112
|
+
items={productRail}
|
|
113
|
+
/>
|
|
114
|
+
</div>
|
|
115
|
+
</ShowcaseWrapper>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Button, CommandPalette, ComponentDocs, ShowcaseWrapper } from "@/components/ui";
|
|
5
|
+
import { IconSearch, IconBolt, IconTuning, IconHome, IconPerson } from "@/components/icons";
|
|
6
|
+
|
|
7
|
+
export default function CommandPaletteShowcase() {
|
|
8
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
9
|
+
|
|
10
|
+
const items = [
|
|
11
|
+
{ id: "1", label: "Go to Dashboard", shortcut: "Cmd+D", icon: <IconHome className="h-5 w-5" />, onSelect: () => {} },
|
|
12
|
+
{ id: "2", label: "Search Events", shortcut: "Cmd+K", icon: <IconSearch className="h-5 w-5" />, onSelect: () => {} },
|
|
13
|
+
{ id: "3", label: "Run Query", shortcut: "Cmd+R", icon: <IconBolt className="h-5 w-5" />, onSelect: () => {} },
|
|
14
|
+
{ id: "4", label: "Settings", shortcut: "Cmd+,", icon: <IconTuning className="h-5 w-5" />, onSelect: () => {} },
|
|
15
|
+
{ id: "5", label: "Profile", icon: <IconPerson className="h-5 w-5" />, onSelect: () => {} },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const code = `import { Button, CommandPalette } from "the-old-ui";
|
|
19
|
+
import { IconSearch, IconBolt, IconTuning, IconHome, IconPerson } from "the-old-ui";
|
|
20
|
+
|
|
21
|
+
<div className="ph-panel">
|
|
22
|
+
<Button onClick={() => setIsOpen(true)}>Open Command Palette</Button>
|
|
23
|
+
<CommandPalette items={items} isOpen={isOpen} onClose={() => setIsOpen(false)} />
|
|
24
|
+
</div>`;
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<ShowcaseWrapper
|
|
28
|
+
title="Command Palette"
|
|
29
|
+
description="Application command launcher with controlled open state and typed item actions."
|
|
30
|
+
code={code}
|
|
31
|
+
filename="CommandPaletteExample.tsx"
|
|
32
|
+
docs={
|
|
33
|
+
<ComponentDocs
|
|
34
|
+
rows={[
|
|
35
|
+
{ name: "items", type: "{ id; label; shortcut?; icon?; onSelect }[]", description: "Commands shown in the palette." },
|
|
36
|
+
{ name: "isOpen", type: "boolean", description: "Controls palette visibility." },
|
|
37
|
+
{ name: "onClose", type: "() => void", description: "Called by escape, backdrop, or selection." },
|
|
38
|
+
]}
|
|
39
|
+
/>
|
|
40
|
+
}
|
|
41
|
+
>
|
|
42
|
+
<div className="ph-panel">
|
|
43
|
+
<Button onClick={() => setIsOpen(true)}>Open Command Palette</Button>
|
|
44
|
+
<CommandPalette items={items} isOpen={isOpen} onClose={() => setIsOpen(false)} />
|
|
45
|
+
</div>
|
|
46
|
+
</ShowcaseWrapper>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ShowcaseWrapper } from "@/components/ui";
|
|
2
|
+
|
|
3
|
+
export default function CountdownShowcase() {
|
|
4
|
+
const code = `
|
|
5
|
+
|
|
6
|
+
<div className="ph-panel">
|
|
7
|
+
<p className="mb-6 text-sm text-ph-subtle">Static split — swap for synced timers once you plug in real experiment deadlines.</p>
|
|
8
|
+
<div className="flex flex-wrap justify-center gap-3 text-ph-ink sm:justify-start">
|
|
9
|
+
{[
|
|
10
|
+
{ v: "04", label: "Days" },
|
|
11
|
+
{ v: "12", label: "Hrs" },
|
|
12
|
+
{ v: "33", label: "Min" },
|
|
13
|
+
{ v: "09", label: "Sec" },
|
|
14
|
+
].map(({ v, label }) => (
|
|
15
|
+
<div key={label} className="flex min-w-[4.75rem] flex-col items-center rounded-xl border border-ph-border bg-ph-surface px-4 py-3 shadow-ph">
|
|
16
|
+
<span className="text-3xl font-bold tabular-nums">{v}</span>
|
|
17
|
+
<span className="text-[11px] font-semibold uppercase tracking-wider text-ph-mutedtext">{label}</span>
|
|
18
|
+
</div>
|
|
19
|
+
))}
|
|
20
|
+
</div>
|
|
21
|
+
</div>`;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<ShowcaseWrapper title="Countdown motif" code={code} filename="CountdownExample.tsx">
|
|
25
|
+
<div className="ph-panel">
|
|
26
|
+
<p className="mb-6 text-sm text-ph-subtle">Static split — swap for synced timers once you plug in real experiment deadlines.</p>
|
|
27
|
+
<div className="flex flex-wrap justify-center gap-3 text-ph-ink sm:justify-start">
|
|
28
|
+
{[
|
|
29
|
+
{ v: "04", label: "Days" },
|
|
30
|
+
{ v: "12", label: "Hrs" },
|
|
31
|
+
{ v: "33", label: "Min" },
|
|
32
|
+
{ v: "09", label: "Sec" },
|
|
33
|
+
].map(({ v, label }) => (
|
|
34
|
+
<div key={label} className="flex min-w-[4.75rem] flex-col items-center rounded-xl border border-ph-border bg-ph-surface px-4 py-3 shadow-ph">
|
|
35
|
+
<span className="text-3xl font-bold tabular-nums">{v}</span>
|
|
36
|
+
<span className="text-[11px] font-semibold uppercase tracking-wider text-ph-mutedtext">{label}</span>
|
|
37
|
+
</div>
|
|
38
|
+
))}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</ShowcaseWrapper>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { IconAreaChart, IconArrowUp, IconCohort, IconPlus } from "@/components/icons";
|
|
2
|
+
import {
|
|
3
|
+
DashboardFiltersBar,
|
|
4
|
+
DashboardGrid,
|
|
5
|
+
DashboardInsightPlaceholder,
|
|
6
|
+
DashboardKpiCard,
|
|
7
|
+
DashboardToolbar,
|
|
8
|
+
DashboardWell,
|
|
9
|
+
InsightMiniCard,
|
|
10
|
+
} from "@/components/dashboard";
|
|
11
|
+
import { Button, ShowcaseWrapper } from "@/components/ui";
|
|
12
|
+
|
|
13
|
+
const insightCards = [
|
|
14
|
+
{
|
|
15
|
+
title: "Weekly active users",
|
|
16
|
+
subtitle: "Last 14 days · product analytics",
|
|
17
|
+
ribbonColour: "var(--ph-product-product-analytics)",
|
|
18
|
+
heights: [40, 55, 48, 62, 58, 70, 52, 45, 68, 72, 65, 80, 75, 88],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
title: "Session length",
|
|
22
|
+
subtitle: "Median minutes · replay cohort",
|
|
23
|
+
ribbonColour: "var(--ph-product-session-replay)",
|
|
24
|
+
heights: [52, 48, 45, 50, 55, 60, 58, 54, 50, 48, 55, 60, 58, 62],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: "Flag evaluations",
|
|
28
|
+
subtitle: "Per minute · infrastructure",
|
|
29
|
+
ribbonColour: "var(--ph-product-feature-flags)",
|
|
30
|
+
heights: [30, 35, 42, 38, 45, 50, 48, 52, 55, 58, 54, 50, 48, 55],
|
|
31
|
+
},
|
|
32
|
+
] as const;
|
|
33
|
+
|
|
34
|
+
export default function DashboardShowcase() {
|
|
35
|
+
const code = `import { IconAreaChart, IconArrowUp, IconCohort, IconPlus } from "the-old-ui";
|
|
36
|
+
import { DashboardFiltersBar, DashboardGrid, DashboardInsightPlaceholder, DashboardKpiCard, DashboardToolbar, DashboardWell, InsightMiniCard } from "the-old-ui";
|
|
37
|
+
import { Button } from "the-old-ui";
|
|
38
|
+
|
|
39
|
+
<DashboardWell className="space-y-6">
|
|
40
|
+
<DashboardToolbar
|
|
41
|
+
title="Marketing overview"
|
|
42
|
+
description="Mock layout · spacing and elevation only"
|
|
43
|
+
actions={
|
|
44
|
+
<Button variant="secondary" size="sm">
|
|
45
|
+
Edit layout
|
|
46
|
+
</Button>
|
|
47
|
+
}
|
|
48
|
+
/>
|
|
49
|
+
|
|
50
|
+
<DashboardFiltersBar className="text-xs">
|
|
51
|
+
<span className="font-semibold text-ph-ink">Last 14 days</span>
|
|
52
|
+
<span className="text-ph-mutedtext">·</span>
|
|
53
|
+
<span>Global cohort</span>
|
|
54
|
+
<Button variant="ghost" size="xs" className="rounded-md px-2">
|
|
55
|
+
Breakdown
|
|
56
|
+
</Button>
|
|
57
|
+
</DashboardFiltersBar>
|
|
58
|
+
|
|
59
|
+
<div className="grid gap-4 md:grid-cols-3">
|
|
60
|
+
<DashboardKpiCard
|
|
61
|
+
icon={<IconArrowUp className="text-ph-brand" aria-hidden />}
|
|
62
|
+
label="Event volume"
|
|
63
|
+
value={<span className="text-ph-brand tabular-nums">2.6M</span>}
|
|
64
|
+
footer={
|
|
65
|
+
<>
|
|
66
|
+
<span className="font-semibold text-emerald-700">▲ 21%</span> vs previous window
|
|
67
|
+
</>
|
|
68
|
+
}
|
|
69
|
+
/>
|
|
70
|
+
<DashboardKpiCard
|
|
71
|
+
icon={<IconCohort className="text-ph-blue" aria-hidden />}
|
|
72
|
+
label="Weekly active users"
|
|
73
|
+
value={<span className="text-ph-blue tabular-nums">12.8K</span>}
|
|
74
|
+
footer="Stable vs trailing 28-day baseline"
|
|
75
|
+
/>
|
|
76
|
+
<DashboardKpiCard
|
|
77
|
+
icon={<IconAreaChart className="text-ph-purple" aria-hidden />}
|
|
78
|
+
label="Experiments exposing"
|
|
79
|
+
value={<span className="text-ph-purple tabular-nums">4</span>}
|
|
80
|
+
footer="Flags + multivariates counted"
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<DashboardGrid>
|
|
85
|
+
{insightCards.map((card) => (
|
|
86
|
+
<InsightMiniCard
|
|
87
|
+
key={card.title}
|
|
88
|
+
title={card.title}
|
|
89
|
+
subtitle={card.subtitle}
|
|
90
|
+
ribbonColour={card.ribbonColour}
|
|
91
|
+
heights={card.heights}
|
|
92
|
+
/>
|
|
93
|
+
))}
|
|
94
|
+
</DashboardGrid>
|
|
95
|
+
|
|
96
|
+
<div className="grid gap-4 md:grid-cols-2">
|
|
97
|
+
<InsightMiniCard
|
|
98
|
+
title="Activation funnel"
|
|
99
|
+
subtitle="Mock · drop-off by step"
|
|
100
|
+
ribbonColour="var(--ph-product-experiments)"
|
|
101
|
+
heights={[88, 72, 58, 44, 32, 28, 24, 22, 20, 18, 16, 15, 14, 13]}
|
|
102
|
+
/>
|
|
103
|
+
<DashboardInsightPlaceholder>
|
|
104
|
+
<IconPlus className="h-8 w-8 text-ph-mutedtext group-hover:text-ph-brand" aria-hidden />
|
|
105
|
+
<span className="text-sm font-medium text-ph-subtle group-hover:text-ph-ink">Add insight</span>
|
|
106
|
+
<span className="max-w-[14rem] text-xs text-ph-mutedtext">Opens the same picker pattern your app uses for new tiles.</span>
|
|
107
|
+
</DashboardInsightPlaceholder>
|
|
108
|
+
</div>
|
|
109
|
+
</DashboardWell>`;
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<ShowcaseWrapper
|
|
113
|
+
title="Dashboard shells"
|
|
114
|
+
description="Inset canvas (DashboardWell) and raised insight tiles (InsightShell / InsightMiniCard) mirror how the PostHog app frames dashboards."
|
|
115
|
+
code={code}
|
|
116
|
+
filename="DashboardExample.tsx"
|
|
117
|
+
>
|
|
118
|
+
<DashboardWell className="space-y-6">
|
|
119
|
+
<DashboardToolbar
|
|
120
|
+
title="Marketing overview"
|
|
121
|
+
description="Mock layout · spacing and elevation only"
|
|
122
|
+
actions={
|
|
123
|
+
<Button variant="secondary" size="sm">
|
|
124
|
+
Edit layout
|
|
125
|
+
</Button>
|
|
126
|
+
}
|
|
127
|
+
/>
|
|
128
|
+
|
|
129
|
+
<DashboardFiltersBar className="text-xs">
|
|
130
|
+
<span className="font-semibold text-ph-ink">Last 14 days</span>
|
|
131
|
+
<span className="text-ph-mutedtext">·</span>
|
|
132
|
+
<span>Global cohort</span>
|
|
133
|
+
<Button variant="ghost" size="xs" className="rounded-md px-2">
|
|
134
|
+
Breakdown
|
|
135
|
+
</Button>
|
|
136
|
+
</DashboardFiltersBar>
|
|
137
|
+
|
|
138
|
+
<div className="grid gap-4 md:grid-cols-3">
|
|
139
|
+
<DashboardKpiCard
|
|
140
|
+
icon={<IconArrowUp className="text-ph-brand" aria-hidden />}
|
|
141
|
+
label="Event volume"
|
|
142
|
+
value={<span className="text-ph-brand tabular-nums">2.6M</span>}
|
|
143
|
+
footer={
|
|
144
|
+
<>
|
|
145
|
+
<span className="font-semibold text-emerald-700">▲ 21%</span> vs previous window
|
|
146
|
+
</>
|
|
147
|
+
}
|
|
148
|
+
/>
|
|
149
|
+
<DashboardKpiCard
|
|
150
|
+
icon={<IconCohort className="text-ph-blue" aria-hidden />}
|
|
151
|
+
label="Weekly active users"
|
|
152
|
+
value={<span className="text-ph-blue tabular-nums">12.8K</span>}
|
|
153
|
+
footer="Stable vs trailing 28-day baseline"
|
|
154
|
+
/>
|
|
155
|
+
<DashboardKpiCard
|
|
156
|
+
icon={<IconAreaChart className="text-ph-purple" aria-hidden />}
|
|
157
|
+
label="Experiments exposing"
|
|
158
|
+
value={<span className="text-ph-purple tabular-nums">4</span>}
|
|
159
|
+
footer="Flags + multivariates counted"
|
|
160
|
+
/>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<DashboardGrid>
|
|
164
|
+
{insightCards.map((card) => (
|
|
165
|
+
<InsightMiniCard
|
|
166
|
+
key={card.title}
|
|
167
|
+
title={card.title}
|
|
168
|
+
subtitle={card.subtitle}
|
|
169
|
+
ribbonColour={card.ribbonColour}
|
|
170
|
+
heights={card.heights}
|
|
171
|
+
/>
|
|
172
|
+
))}
|
|
173
|
+
</DashboardGrid>
|
|
174
|
+
|
|
175
|
+
<div className="grid gap-4 md:grid-cols-2">
|
|
176
|
+
<InsightMiniCard
|
|
177
|
+
title="Activation funnel"
|
|
178
|
+
subtitle="Mock · drop-off by step"
|
|
179
|
+
ribbonColour="var(--ph-product-experiments)"
|
|
180
|
+
heights={[88, 72, 58, 44, 32, 28, 24, 22, 20, 18, 16, 15, 14, 13]}
|
|
181
|
+
/>
|
|
182
|
+
<DashboardInsightPlaceholder>
|
|
183
|
+
<IconPlus className="h-8 w-8 text-ph-mutedtext group-hover:text-ph-brand" aria-hidden />
|
|
184
|
+
<span className="text-sm font-medium text-ph-subtle group-hover:text-ph-ink">Add insight</span>
|
|
185
|
+
<span className="max-w-[14rem] text-xs text-ph-mutedtext">Opens the same picker pattern your app uses for new tiles.</span>
|
|
186
|
+
</DashboardInsightPlaceholder>
|
|
187
|
+
</div>
|
|
188
|
+
</DashboardWell>
|
|
189
|
+
</ShowcaseWrapper>
|
|
190
|
+
);
|
|
191
|
+
}
|