@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,199 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { IconBell, IconPerson } from "@/components/icons";
|
|
4
|
+
import { Button, DropdownItem, DropdownMenu, SearchInput, ShowcaseWrapper } from "@/components/ui";
|
|
5
|
+
|
|
6
|
+
export default function NavigationShowcase() {
|
|
7
|
+
const code = `import { IconBell, IconPerson } from "the-old-ui";
|
|
8
|
+
import { Button, DropdownItem, DropdownMenu, SearchInput } from "the-old-ui";
|
|
9
|
+
|
|
10
|
+
<div className="space-y-8">
|
|
11
|
+
<div className="ph-panel">
|
|
12
|
+
<h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Top bar density</h3>
|
|
13
|
+
<div className="ph-navbar-demo justify-between gap-4">
|
|
14
|
+
<span className="text-lg font-bold text-ph-brand">posthog</span>
|
|
15
|
+
<div className="flex flex-1 flex-wrap items-center justify-end gap-2">
|
|
16
|
+
<SearchInput
|
|
17
|
+
label="Jump to"
|
|
18
|
+
hideLabel
|
|
19
|
+
shortcut="Cmd K"
|
|
20
|
+
placeholder="Jump to…"
|
|
21
|
+
density="compact"
|
|
22
|
+
/>
|
|
23
|
+
<Button type="button" variant="ghost" shape="circle" className="relative" aria-label="Notifications">
|
|
24
|
+
<IconBell className="h-5 w-5 text-ph-mutedtext" />
|
|
25
|
+
<span className="absolute right-2 top-2 h-2 w-2 rounded-full bg-ph-brand ring-2 ring-ph-surface" />
|
|
26
|
+
</Button>
|
|
27
|
+
<DropdownMenu
|
|
28
|
+
align="end"
|
|
29
|
+
aria-label="Account menu"
|
|
30
|
+
trigger={
|
|
31
|
+
<span className="flex h-9 w-9 cursor-pointer items-center justify-center rounded-full bg-ph-muted text-ph-ink">
|
|
32
|
+
<IconPerson className="h-5 w-5" aria-hidden />
|
|
33
|
+
</span>
|
|
34
|
+
}
|
|
35
|
+
>
|
|
36
|
+
<DropdownItem>Personal API keys</DropdownItem>
|
|
37
|
+
<DropdownItem>Organisation settings</DropdownItem>
|
|
38
|
+
</DropdownMenu>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div className="ph-panel flex gap-10">
|
|
44
|
+
<div>
|
|
45
|
+
<h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Side navigation</h3>
|
|
46
|
+
<ul className="w-52 space-y-1 text-sm font-medium">
|
|
47
|
+
<li>
|
|
48
|
+
<a href="#" className="block rounded-md bg-ph-muted px-3 py-2 text-ph-ink">
|
|
49
|
+
Home
|
|
50
|
+
</a>
|
|
51
|
+
</li>
|
|
52
|
+
<li>
|
|
53
|
+
<a href="#" className="block rounded-md px-3 py-2 text-ph-subtle hover:bg-ph-muted/70">
|
|
54
|
+
Data pipeline
|
|
55
|
+
</a>
|
|
56
|
+
</li>
|
|
57
|
+
<li>
|
|
58
|
+
<details open className="ph-details [&>summary::-webkit-details-marker]:hidden">
|
|
59
|
+
<summary className="cursor-pointer list-none px-3 py-2 text-ph-mutedtext">Warehouse</summary>
|
|
60
|
+
<ul className="mt-1 space-y-1 border-l border-ph-border pl-5">
|
|
61
|
+
<li>
|
|
62
|
+
<a href="#" className="block py-1 text-ph-subtle hover:text-ph-ink">
|
|
63
|
+
Sources
|
|
64
|
+
</a>
|
|
65
|
+
</li>
|
|
66
|
+
<li>
|
|
67
|
+
<a href="#" className="block py-1 text-ph-subtle hover:text-ph-ink">
|
|
68
|
+
Views
|
|
69
|
+
</a>
|
|
70
|
+
</li>
|
|
71
|
+
</ul>
|
|
72
|
+
</details>
|
|
73
|
+
</li>
|
|
74
|
+
</ul>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<div className="flex-1">
|
|
78
|
+
<h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Timeline steps</h3>
|
|
79
|
+
<ol className="ph-steps">
|
|
80
|
+
<li className="flex flex-col items-center gap-2">
|
|
81
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-ph-brand text-xs font-bold text-white">
|
|
82
|
+
1
|
|
83
|
+
</span>
|
|
84
|
+
<span>Install snippet</span>
|
|
85
|
+
</li>
|
|
86
|
+
<li className="flex flex-col items-center gap-2 opacity-60">
|
|
87
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-full border border-dashed border-ph-border text-xs">
|
|
88
|
+
2
|
|
89
|
+
</span>
|
|
90
|
+
<span>Send test event</span>
|
|
91
|
+
</li>
|
|
92
|
+
<li className="flex flex-col items-center gap-2 opacity-60">
|
|
93
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-full border border-dashed border-ph-border text-xs">
|
|
94
|
+
3
|
|
95
|
+
</span>
|
|
96
|
+
<span>Invite team</span>
|
|
97
|
+
</li>
|
|
98
|
+
</ol>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>`;
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<ShowcaseWrapper title="Navigation chrome" code={code} filename="NavigationExample.tsx">
|
|
105
|
+
<div className="space-y-8">
|
|
106
|
+
<div className="ph-panel">
|
|
107
|
+
<h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Top bar density</h3>
|
|
108
|
+
<div className="ph-navbar-demo justify-between gap-4">
|
|
109
|
+
<span className="text-lg font-bold text-ph-brand">posthog</span>
|
|
110
|
+
<div className="flex flex-1 flex-wrap items-center justify-end gap-2">
|
|
111
|
+
<SearchInput
|
|
112
|
+
label="Jump to"
|
|
113
|
+
hideLabel
|
|
114
|
+
shortcut="Cmd K"
|
|
115
|
+
placeholder="Jump to…"
|
|
116
|
+
density="compact"
|
|
117
|
+
/>
|
|
118
|
+
<Button type="button" variant="ghost" shape="circle" className="relative" aria-label="Notifications">
|
|
119
|
+
<IconBell className="h-5 w-5 text-ph-mutedtext" />
|
|
120
|
+
<span className="absolute right-2 top-2 h-2 w-2 rounded-full bg-ph-brand ring-2 ring-ph-surface" />
|
|
121
|
+
</Button>
|
|
122
|
+
<DropdownMenu
|
|
123
|
+
align="end"
|
|
124
|
+
aria-label="Account menu"
|
|
125
|
+
trigger={
|
|
126
|
+
<span className="flex h-9 w-9 cursor-pointer items-center justify-center rounded-full bg-ph-muted text-ph-ink">
|
|
127
|
+
<IconPerson className="h-5 w-5" aria-hidden />
|
|
128
|
+
</span>
|
|
129
|
+
}
|
|
130
|
+
>
|
|
131
|
+
<DropdownItem>Personal API keys</DropdownItem>
|
|
132
|
+
<DropdownItem>Organisation settings</DropdownItem>
|
|
133
|
+
</DropdownMenu>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div className="ph-panel flex gap-10">
|
|
139
|
+
<div>
|
|
140
|
+
<h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Side navigation</h3>
|
|
141
|
+
<ul className="w-52 space-y-1 text-sm font-medium">
|
|
142
|
+
<li>
|
|
143
|
+
<a href="#" className="block rounded-md bg-ph-muted px-3 py-2 text-ph-ink">
|
|
144
|
+
Home
|
|
145
|
+
</a>
|
|
146
|
+
</li>
|
|
147
|
+
<li>
|
|
148
|
+
<a href="#" className="block rounded-md px-3 py-2 text-ph-subtle hover:bg-ph-muted/70">
|
|
149
|
+
Data pipeline
|
|
150
|
+
</a>
|
|
151
|
+
</li>
|
|
152
|
+
<li>
|
|
153
|
+
<details open className="ph-details [&>summary::-webkit-details-marker]:hidden">
|
|
154
|
+
<summary className="cursor-pointer list-none px-3 py-2 text-ph-mutedtext">Warehouse</summary>
|
|
155
|
+
<ul className="mt-1 space-y-1 border-l border-ph-border pl-5">
|
|
156
|
+
<li>
|
|
157
|
+
<a href="#" className="block py-1 text-ph-subtle hover:text-ph-ink">
|
|
158
|
+
Sources
|
|
159
|
+
</a>
|
|
160
|
+
</li>
|
|
161
|
+
<li>
|
|
162
|
+
<a href="#" className="block py-1 text-ph-subtle hover:text-ph-ink">
|
|
163
|
+
Views
|
|
164
|
+
</a>
|
|
165
|
+
</li>
|
|
166
|
+
</ul>
|
|
167
|
+
</details>
|
|
168
|
+
</li>
|
|
169
|
+
</ul>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<div className="flex-1">
|
|
173
|
+
<h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Timeline steps</h3>
|
|
174
|
+
<ol className="ph-steps">
|
|
175
|
+
<li className="flex flex-col items-center gap-2">
|
|
176
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-ph-brand text-xs font-bold text-white">
|
|
177
|
+
1
|
|
178
|
+
</span>
|
|
179
|
+
<span>Install snippet</span>
|
|
180
|
+
</li>
|
|
181
|
+
<li className="flex flex-col items-center gap-2 opacity-60">
|
|
182
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-full border border-dashed border-ph-border text-xs">
|
|
183
|
+
2
|
|
184
|
+
</span>
|
|
185
|
+
<span>Send test event</span>
|
|
186
|
+
</li>
|
|
187
|
+
<li className="flex flex-col items-center gap-2 opacity-60">
|
|
188
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-full border border-dashed border-ph-border text-xs">
|
|
189
|
+
3
|
|
190
|
+
</span>
|
|
191
|
+
<span>Invite team</span>
|
|
192
|
+
</li>
|
|
193
|
+
</ol>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</ShowcaseWrapper>
|
|
198
|
+
);
|
|
199
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { IconSpinner } from "@/components/icons";
|
|
2
|
+
import { ComponentDocs, Progress, ShowcaseWrapper } from "@/components/ui";
|
|
3
|
+
|
|
4
|
+
export default function ProgressShowcase() {
|
|
5
|
+
const code = `import { Progress } from "the-old-ui";
|
|
6
|
+
|
|
7
|
+
<div className="space-y-8">
|
|
8
|
+
<div className="ph-panel space-y-6">
|
|
9
|
+
<Progress label="Ingest backlog" value={72} color="bg-ph-brand" showPercentage />
|
|
10
|
+
<Progress label="Exports" value={45} color="bg-ph-blue" showPercentage />
|
|
11
|
+
<Progress label="LLM evaluations" value={28} color="bg-ph-purple" showPercentage />
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div className="ph-panel flex flex-wrap items-center gap-10">
|
|
15
|
+
<Progress value={72} color="bg-ph-brand" size="lg" className="w-48" />
|
|
16
|
+
<Progress value={45} color="bg-ph-blue" size="lg" className="w-48" />
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div className="ph-panel flex flex-wrap items-center gap-8">
|
|
20
|
+
<span className="ph-loading" role="status" aria-label="Loading" />
|
|
21
|
+
<IconSpinner className="h-6 w-6 text-ph-brand" role="status" aria-label="Loading" />
|
|
22
|
+
<div className="ph-loading-dots" role="status" aria-label="Loading">
|
|
23
|
+
<span />
|
|
24
|
+
<span />
|
|
25
|
+
<span />
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>`;
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<ShowcaseWrapper
|
|
32
|
+
title="Progress & loading"
|
|
33
|
+
description="Linear progress bars, spinners, and skeleton placeholders with semantic colour support."
|
|
34
|
+
code={code}
|
|
35
|
+
filename="ProgressExample.tsx"
|
|
36
|
+
docs={
|
|
37
|
+
<ComponentDocs
|
|
38
|
+
rows={[
|
|
39
|
+
{ name: "value", type: "number", description: "Current value." },
|
|
40
|
+
{ name: "max", type: "number", defaultValue: "100", description: "Maximum value." },
|
|
41
|
+
{ name: "color", type: "string", defaultValue: "bg-ph-brand", description: "Tailwind colour class for the bar." },
|
|
42
|
+
{ name: "label", type: "string", description: "Label shown above the bar." },
|
|
43
|
+
{ name: "showPercentage", type: "boolean", defaultValue: "false", description: "Show percentage text." },
|
|
44
|
+
{ name: "size", type: "sm | md | lg", defaultValue: "md", description: "Bar height." },
|
|
45
|
+
]}
|
|
46
|
+
/>
|
|
47
|
+
}
|
|
48
|
+
>
|
|
49
|
+
<div className="space-y-8">
|
|
50
|
+
<div className="ph-panel space-y-6">
|
|
51
|
+
<h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Linear bars</h3>
|
|
52
|
+
<Progress label="Ingest backlog" value={72} color="bg-ph-brand" showPercentage />
|
|
53
|
+
<Progress label="Exports" value={45} color="bg-ph-blue" showPercentage />
|
|
54
|
+
<Progress label="LLM evaluations" value={28} color="bg-ph-purple" showPercentage />
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div className="ph-panel flex flex-wrap items-center gap-10">
|
|
58
|
+
<div className="w-full">
|
|
59
|
+
<h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Large bars</h3>
|
|
60
|
+
<div className="flex gap-10">
|
|
61
|
+
<Progress value={72} color="bg-ph-brand" size="lg" className="w-48" />
|
|
62
|
+
<Progress value={45} color="bg-ph-blue" size="lg" className="w-48" />
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div className="ph-panel flex flex-wrap items-center gap-8">
|
|
68
|
+
<div className="flex items-center gap-3 text-ph-subtle">
|
|
69
|
+
<span className="ph-loading" role="status" aria-label="Loading" />
|
|
70
|
+
<code className="ph-kbd">ph-loading</code> — CSS spinner
|
|
71
|
+
</div>
|
|
72
|
+
<div className="flex items-center gap-3 text-ph-subtle">
|
|
73
|
+
<IconSpinner className="h-6 w-6 text-ph-brand" role="status" aria-label="Loading" />
|
|
74
|
+
<code className="ph-kbd">IconSpinner</code> — Animated icon
|
|
75
|
+
</div>
|
|
76
|
+
<div className="ph-loading-dots" role="status" aria-label="Loading">
|
|
77
|
+
<span />
|
|
78
|
+
<span />
|
|
79
|
+
<span />
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</ShowcaseWrapper>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { ComponentDocs, SegmentedControl, ShowcaseWrapper } from "@/components/ui";
|
|
5
|
+
import { IconGridView, IconListView } from "@/components/icons";
|
|
6
|
+
|
|
7
|
+
export default function SegmentedControlShowcase() {
|
|
8
|
+
const [view, setView] = useState("grid");
|
|
9
|
+
|
|
10
|
+
const options = [
|
|
11
|
+
{ value: "grid", label: "Grid", icon: <IconGridView className="h-4 w-4" /> },
|
|
12
|
+
{ value: "list", label: "List", icon: <IconListView className="h-4 w-4" /> },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const code = `import { SegmentedControl } from "the-old-ui";
|
|
16
|
+
import { IconGridView, IconListView } from "the-old-ui";
|
|
17
|
+
|
|
18
|
+
<div className="ph-panel">
|
|
19
|
+
<SegmentedControl options={options} value={view} onChange={setView} />
|
|
20
|
+
<div className="mt-4 rounded-lg bg-ph-muted p-4 text-sm text-ph-subtle">
|
|
21
|
+
Selected: <span className="font-semibold text-ph-ink">{view}</span>
|
|
22
|
+
</div>
|
|
23
|
+
</div>`;
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<ShowcaseWrapper
|
|
27
|
+
title="Segmented Control"
|
|
28
|
+
description="Compact controlled switch for mutually exclusive display modes."
|
|
29
|
+
code={code}
|
|
30
|
+
filename="SegmentedControlExample.tsx"
|
|
31
|
+
docs={
|
|
32
|
+
<ComponentDocs
|
|
33
|
+
rows={[
|
|
34
|
+
{ name: "options", type: "{ value; label; icon? }[]", description: "Segments to render." },
|
|
35
|
+
{ name: "value", type: "string", description: "Currently selected value." },
|
|
36
|
+
{ name: "onChange", type: "(value: string) => void", description: "Called when a segment is selected." },
|
|
37
|
+
]}
|
|
38
|
+
/>
|
|
39
|
+
}
|
|
40
|
+
>
|
|
41
|
+
<div className="ph-panel">
|
|
42
|
+
<SegmentedControl options={options} value={view} onChange={setView} />
|
|
43
|
+
<div className="mt-4 rounded-lg bg-ph-muted p-4 text-sm text-ph-subtle">
|
|
44
|
+
Selected: <span className="font-semibold text-ph-ink">{view}</span>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</ShowcaseWrapper>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { CodeBlock, H3, P, Panel, ThemeSwitcher } from "@/components/ui";
|
|
5
|
+
import { THEMES } from "@/themes";
|
|
6
|
+
|
|
7
|
+
const themePairs = [
|
|
8
|
+
{ name: "HedgeHog", light: "hedgehog-light", dark: "hedgehog-dark" },
|
|
9
|
+
{ name: "Sheets", light: "sheets", dark: "sheets-dark" },
|
|
10
|
+
{ name: "Note", light: "note", dark: "note-dark" },
|
|
11
|
+
{ name: "Presentation", light: "presentation", dark: "presentation-dark" },
|
|
12
|
+
{ name: "Socials", light: "socials", dark: "socials-dark" },
|
|
13
|
+
{ name: "Chats", light: "chats-light", dark: "chats-dark" },
|
|
14
|
+
{ name: "Catppuccin", light: "catppuccin-light", dark: "catppuccin-dark" },
|
|
15
|
+
{ name: "Xenide", light: "xenide-light", dark: "xenide-dark" },
|
|
16
|
+
{ name: "GitHub", light: "github-light", dark: "github-dark" },
|
|
17
|
+
{ name: "Rose Pine", light: "rosepine-light", dark: "rosepine-dark" },
|
|
18
|
+
{ name: "TurtleTime", light: "turtletime", dark: "turtletime-dark" },
|
|
19
|
+
{ name: "Bikini Bottom", light: "bikini-bottom", dark: "bikini-bottom-dark" },
|
|
20
|
+
{ name: "Notion", light: "notion", dark: "notion-dark" },
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
const guideTokens = [
|
|
24
|
+
{ label: "canvas", token: "--ph-canvas", text: "text-ph-ink" },
|
|
25
|
+
{ label: "surface", token: "--ph-surface", text: "text-ph-ink" },
|
|
26
|
+
{ label: "muted", token: "--ph-muted", text: "text-ph-ink" },
|
|
27
|
+
{ label: "toolbar", token: "--ph-toolbar", text: "text-ph-ink" },
|
|
28
|
+
{ label: "border", token: "--ph-border", text: "text-ph-ink" },
|
|
29
|
+
{ label: "accent", token: "--ph-accent", text: "text-white" },
|
|
30
|
+
{ label: "blue", token: "--ph-blue", text: "text-white" },
|
|
31
|
+
{ label: "purple", token: "--ph-purple", text: "text-white" },
|
|
32
|
+
{ label: "success", token: "--ph-success", text: "text-white" },
|
|
33
|
+
{ label: "warning", token: "--ph-warning", text: "text-white" },
|
|
34
|
+
{ label: "danger", token: "--ph-danger", text: "text-white" },
|
|
35
|
+
{ label: "info", token: "--ph-info", text: "text-white" },
|
|
36
|
+
] as const;
|
|
37
|
+
|
|
38
|
+
const dataTokens = [1, 2, 3, 4, 5, 6, 7].map((item) => ({
|
|
39
|
+
label: `data ${item}`,
|
|
40
|
+
token: `--ph-data-${item}`,
|
|
41
|
+
text: "text-white",
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
const installCode = `bun add the-old-ui
|
|
45
|
+
# or
|
|
46
|
+
npm install the-old-ui`;
|
|
47
|
+
|
|
48
|
+
const layoutCode = `// app/layout.tsx
|
|
49
|
+
import "the-old-ui/styles.css";
|
|
50
|
+
import { THEME_INIT_SCRIPT, ThemeManager } from "the-old-ui";
|
|
51
|
+
|
|
52
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
53
|
+
return (
|
|
54
|
+
<html lang="en" data-theme="hedgehog-light" suppressHydrationWarning>
|
|
55
|
+
<head>
|
|
56
|
+
<script dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }} />
|
|
57
|
+
</head>
|
|
58
|
+
<body>
|
|
59
|
+
<ThemeManager>{children}</ThemeManager>
|
|
60
|
+
</body>
|
|
61
|
+
</html>
|
|
62
|
+
);
|
|
63
|
+
}`;
|
|
64
|
+
|
|
65
|
+
const tailwindCode = `// tailwind.config.ts
|
|
66
|
+
import theOldUiPreset from "the-old-ui/tailwind-preset";
|
|
67
|
+
|
|
68
|
+
export default {
|
|
69
|
+
presets: [theOldUiPreset],
|
|
70
|
+
content: [
|
|
71
|
+
"./src/**/*.{ts,tsx}",
|
|
72
|
+
"./app/**/*.{ts,tsx}",
|
|
73
|
+
"./node_modules/the-old-ui/dist/**/*.{js,mjs}",
|
|
74
|
+
],
|
|
75
|
+
};`;
|
|
76
|
+
|
|
77
|
+
const switchCode = `import { ThemeSwitcher, persistTheme } from "the-old-ui";
|
|
78
|
+
|
|
79
|
+
<ThemeSwitcher />
|
|
80
|
+
|
|
81
|
+
// Or switch manually
|
|
82
|
+
persistTheme("sheets-dark");`;
|
|
83
|
+
|
|
84
|
+
const customThemeCode = `/* app/globals.css */
|
|
85
|
+
@import "the-old-ui/styles.css";
|
|
86
|
+
|
|
87
|
+
[data-theme="my-theme-light"] {
|
|
88
|
+
color-scheme: light;
|
|
89
|
+
|
|
90
|
+
--ph-canvas: #f8f5ef;
|
|
91
|
+
--ph-surface: #ffffff;
|
|
92
|
+
--ph-muted: #eee8dd;
|
|
93
|
+
--ph-toolbar: #e5dccd;
|
|
94
|
+
--ph-border: #d7cbb8;
|
|
95
|
+
--ph-border-strong: #a99b87;
|
|
96
|
+
|
|
97
|
+
--ph-text-primary: #15110c;
|
|
98
|
+
--ph-text-secondary: #4d4337;
|
|
99
|
+
--ph-text-tertiary: #796f63;
|
|
100
|
+
|
|
101
|
+
--ph-accent: #f97316;
|
|
102
|
+
--ph-accent-hover: #ea580c;
|
|
103
|
+
--ph-blue: #2563eb;
|
|
104
|
+
--ph-purple: #7c3aed;
|
|
105
|
+
--ph-success: #15803d;
|
|
106
|
+
--ph-warning: #b45309;
|
|
107
|
+
--ph-danger: #dc2626;
|
|
108
|
+
--ph-info: #2563eb;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
[data-theme="my-theme-dark"] {
|
|
112
|
+
color-scheme: dark;
|
|
113
|
+
|
|
114
|
+
--ph-canvas: #11100e;
|
|
115
|
+
--ph-surface: #191713;
|
|
116
|
+
--ph-muted: #242018;
|
|
117
|
+
--ph-toolbar: #2e281f;
|
|
118
|
+
--ph-border: #443a2b;
|
|
119
|
+
--ph-border-strong: #7a6a54;
|
|
120
|
+
|
|
121
|
+
--ph-text-primary: #fff7ed;
|
|
122
|
+
--ph-text-secondary: #d8c8b6;
|
|
123
|
+
--ph-text-tertiary: #a89985;
|
|
124
|
+
|
|
125
|
+
--ph-accent: #fb923c;
|
|
126
|
+
--ph-accent-hover: #fdba74;
|
|
127
|
+
--ph-blue: #60a5fa;
|
|
128
|
+
--ph-purple: #a78bfa;
|
|
129
|
+
--ph-success: #4ade80;
|
|
130
|
+
--ph-warning: #facc15;
|
|
131
|
+
--ph-danger: #f87171;
|
|
132
|
+
--ph-info: #60a5fa;
|
|
133
|
+
}`;
|
|
134
|
+
|
|
135
|
+
const registryCode = `// Add to src/themes/registry.ts if this repo should show it in ThemeSwitcher
|
|
136
|
+
{
|
|
137
|
+
id: "my-theme-light",
|
|
138
|
+
name: "My Theme Light",
|
|
139
|
+
description: "Custom light palette.",
|
|
140
|
+
colorScheme: "light",
|
|
141
|
+
group: "Custom",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: "my-theme-dark",
|
|
145
|
+
name: "My Theme Dark",
|
|
146
|
+
description: "Custom dark palette.",
|
|
147
|
+
colorScheme: "dark",
|
|
148
|
+
group: "Custom",
|
|
149
|
+
}`;
|
|
150
|
+
|
|
151
|
+
export default function SetupThemeShowcase() {
|
|
152
|
+
const [activeTheme, setActiveTheme] = useState("hedgehog-light");
|
|
153
|
+
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
const root = document.documentElement;
|
|
156
|
+
const update = () => setActiveTheme(root.getAttribute("data-theme") || "hedgehog-light");
|
|
157
|
+
update();
|
|
158
|
+
|
|
159
|
+
const observer = new MutationObserver(update);
|
|
160
|
+
observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] });
|
|
161
|
+
return () => observer.disconnect();
|
|
162
|
+
}, []);
|
|
163
|
+
|
|
164
|
+
const activeThemeCode = useMemo(() => {
|
|
165
|
+
const theme = THEMES.find((item) => item.id === activeTheme);
|
|
166
|
+
return `// Current selected theme in this demo\n${JSON.stringify({
|
|
167
|
+
id: activeTheme,
|
|
168
|
+
name: theme?.name ?? activeTheme,
|
|
169
|
+
colorScheme: theme?.colorScheme ?? "light",
|
|
170
|
+
group: theme?.group ?? "Custom",
|
|
171
|
+
}, null, 2)}`;
|
|
172
|
+
}, [activeTheme]);
|
|
173
|
+
|
|
174
|
+
const themeListCode = useMemo(() => {
|
|
175
|
+
return `export const themePairs = ${JSON.stringify(themePairs, null, 2)} as const;`;
|
|
176
|
+
}, []);
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<div className="space-y-8">
|
|
180
|
+
<Panel className="space-y-4">
|
|
181
|
+
<H3>Setup</H3>
|
|
182
|
+
<P tone="subtle">
|
|
183
|
+
This demo is also the docs. A consuming app imports the package CSS once, adds the Tailwind preset, then switches palettes through <code className="ph-kbd">html[data-theme]</code>.
|
|
184
|
+
</P>
|
|
185
|
+
<div className="grid gap-4 lg:grid-cols-2">
|
|
186
|
+
<CodeBlock code={installCode} filename="install.sh" language="bash" />
|
|
187
|
+
<CodeBlock code={tailwindCode} filename="tailwind.config.ts" />
|
|
188
|
+
</div>
|
|
189
|
+
<CodeBlock code={layoutCode} filename="app/layout.tsx" />
|
|
190
|
+
</Panel>
|
|
191
|
+
|
|
192
|
+
<Panel className="space-y-4">
|
|
193
|
+
<div className="flex flex-wrap items-center justify-between gap-4">
|
|
194
|
+
<div>
|
|
195
|
+
<H3>Theme Switching</H3>
|
|
196
|
+
<P tone="subtle">Each default palette is a light/dark pair. Pick one below and copy the active theme ID.</P>
|
|
197
|
+
</div>
|
|
198
|
+
<ThemeSwitcher />
|
|
199
|
+
</div>
|
|
200
|
+
<div className="grid gap-4 lg:grid-cols-2">
|
|
201
|
+
<CodeBlock code={activeThemeCode} filename="current-theme.ts" />
|
|
202
|
+
<CodeBlock code={switchCode} filename="ThemeSwitch.tsx" />
|
|
203
|
+
</div>
|
|
204
|
+
</Panel>
|
|
205
|
+
|
|
206
|
+
<Panel className="space-y-4">
|
|
207
|
+
<H3>Default Theme Pairs</H3>
|
|
208
|
+
<P tone="subtle">Use these IDs with <code className="ph-kbd">data-theme</code> or <code className="ph-kbd">persistTheme()</code>.</P>
|
|
209
|
+
<CodeBlock code={themeListCode} filename="theme-pairs.ts" />
|
|
210
|
+
</Panel>
|
|
211
|
+
|
|
212
|
+
<Panel className="space-y-5">
|
|
213
|
+
<div>
|
|
214
|
+
<H3>Theme Color Guide</H3>
|
|
215
|
+
<P tone="subtle">
|
|
216
|
+
Every built-in theme is rendered below with its own <code className="ph-kbd">data-theme</code> attribute. These swatches are the guide for what each token becomes in that theme.
|
|
217
|
+
</P>
|
|
218
|
+
</div>
|
|
219
|
+
<div className="grid gap-4 lg:grid-cols-2">
|
|
220
|
+
{THEMES.map((theme) => (
|
|
221
|
+
<div
|
|
222
|
+
key={theme.id}
|
|
223
|
+
data-theme={theme.id}
|
|
224
|
+
className="rounded-xl border border-ph-border bg-ph-canvas p-4 shadow-ph"
|
|
225
|
+
>
|
|
226
|
+
<div className="mb-3 flex items-baseline justify-between gap-3">
|
|
227
|
+
<div>
|
|
228
|
+
<h4 className="font-semibold text-ph-ink">{theme.name}</h4>
|
|
229
|
+
<p className="text-xs text-ph-mutedtext">{theme.id}</p>
|
|
230
|
+
</div>
|
|
231
|
+
<span className="rounded-full border border-ph-border bg-ph-surface px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-ph-mutedtext">
|
|
232
|
+
{theme.colorScheme}
|
|
233
|
+
</span>
|
|
234
|
+
</div>
|
|
235
|
+
<div className="grid grid-cols-3 gap-2 sm:grid-cols-4">
|
|
236
|
+
{[...guideTokens, ...dataTokens].map((item) => (
|
|
237
|
+
<div
|
|
238
|
+
key={item.token}
|
|
239
|
+
className={`rounded-lg border border-ph-border p-2 ${item.text}`}
|
|
240
|
+
style={{ background: `var(${item.token})` }}
|
|
241
|
+
>
|
|
242
|
+
<div className="text-[10px] font-bold uppercase tracking-wide">{item.label}</div>
|
|
243
|
+
<div className="mt-1 truncate font-mono text-[9px] opacity-80">{item.token}</div>
|
|
244
|
+
</div>
|
|
245
|
+
))}
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
248
|
+
))}
|
|
249
|
+
</div>
|
|
250
|
+
</Panel>
|
|
251
|
+
|
|
252
|
+
<Panel className="space-y-4">
|
|
253
|
+
<H3>Custom Light & Dark Theme</H3>
|
|
254
|
+
<P tone="subtle">Custom themes are DaisyUI-style: define one light token block and one dark token block. Components read semantic tokens, not hardcoded colours.</P>
|
|
255
|
+
<div className="grid gap-4 lg:grid-cols-2">
|
|
256
|
+
<CodeBlock code={customThemeCode} filename="custom-theme.css" language="css" />
|
|
257
|
+
<CodeBlock code={registryCode} filename="registry.ts" />
|
|
258
|
+
</div>
|
|
259
|
+
</Panel>
|
|
260
|
+
</div>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ShowcaseWrapper } from "@/components/ui";
|
|
2
|
+
|
|
3
|
+
export default function StackShowcase() {
|
|
4
|
+
const code = `
|
|
5
|
+
|
|
6
|
+
<div className="rounded-xl border border-ph-border bg-ph-muted p-10">
|
|
7
|
+
<div className="relative mx-auto h-44 w-48">
|
|
8
|
+
<div className="absolute inset-3 translate-x-4 translate-y-4 rounded-xl border border-ph-border bg-ph-toolbar shadow-ph ring-8 ring-ph-muted" />
|
|
9
|
+
<div className="absolute inset-y-7 left-8 right-[-1rem] translate-x-1 rounded-xl border border-ph-border bg-ph-blue text-center text-xs font-semibold uppercase leading-[4.75rem] text-white shadow-ph ring-8 ring-ph-muted">
|
|
10
|
+
Replay
|
|
11
|
+
</div>
|
|
12
|
+
<div className="absolute inset-x-5 top-0 flex h-[5.75rem] items-center justify-center rounded-xl border border-ph-border bg-ph-surface shadow-ph-md ring-8 ring-ph-muted">
|
|
13
|
+
<span className="text-sm font-bold text-ph-brand">Trends insight</span>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>`;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<ShowcaseWrapper title="Stacked surfaces" code={code} filename="StackExample.tsx">
|
|
20
|
+
<div className="rounded-xl border border-ph-border bg-ph-muted p-10">
|
|
21
|
+
<div className="relative mx-auto h-44 w-48">
|
|
22
|
+
<div className="absolute inset-3 translate-x-4 translate-y-4 rounded-xl border border-ph-border bg-ph-toolbar shadow-ph ring-8 ring-ph-muted" />
|
|
23
|
+
<div className="absolute inset-y-7 left-8 right-[-1rem] translate-x-1 rounded-xl border border-ph-border bg-ph-blue text-center text-xs font-semibold uppercase leading-[4.75rem] text-white shadow-ph ring-8 ring-ph-muted">
|
|
24
|
+
Replay
|
|
25
|
+
</div>
|
|
26
|
+
<div className="absolute inset-x-5 top-0 flex h-[5.75rem] items-center justify-center rounded-xl border border-ph-border bg-ph-surface shadow-ph-md ring-8 ring-ph-muted">
|
|
27
|
+
<span className="text-sm font-bold text-ph-brand">Trends insight</span>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</ShowcaseWrapper>
|
|
32
|
+
);
|
|
33
|
+
}
|