@xenide-io/the-old-ui-theme 0.2.5 → 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-FWCSY2DS.mjs +37 -0
- 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 +655 -378
- package/dist/index.mjs +348 -2695
- package/dist/tailwind-preset.mjs +2 -0
- 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 +13 -5
- 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,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bespoke Lemon glyphs from PostHog open source — filled Material / product paths,
|
|
3
|
+
* not Lucide stroke icons.
|
|
4
|
+
*/
|
|
5
|
+
import {
|
|
6
|
+
IconActivity,
|
|
7
|
+
IconAreaChart,
|
|
8
|
+
IconArrowDown,
|
|
9
|
+
IconArrowUp,
|
|
10
|
+
IconBell,
|
|
11
|
+
IconBellOff,
|
|
12
|
+
IconBolt,
|
|
13
|
+
IconBox,
|
|
14
|
+
IconCancel,
|
|
15
|
+
IconCheck,
|
|
16
|
+
IconCheckCircle,
|
|
17
|
+
IconChevronDown,
|
|
18
|
+
IconChevronLeft,
|
|
19
|
+
IconChevronRight,
|
|
20
|
+
IconClipboardEdit,
|
|
21
|
+
IconClose,
|
|
22
|
+
IconCohort,
|
|
23
|
+
IconCopy,
|
|
24
|
+
IconCumulativeChart,
|
|
25
|
+
IconDatabase,
|
|
26
|
+
IconDownload,
|
|
27
|
+
IconEdit,
|
|
28
|
+
IconErrorOutline,
|
|
29
|
+
IconExclamation,
|
|
30
|
+
IconFlag,
|
|
31
|
+
IconFlare,
|
|
32
|
+
IconFlask,
|
|
33
|
+
IconGift,
|
|
34
|
+
IconGridView,
|
|
35
|
+
IconHandClick,
|
|
36
|
+
IconHome,
|
|
37
|
+
IconLayers,
|
|
38
|
+
IconListView,
|
|
39
|
+
IconLogout,
|
|
40
|
+
IconMail,
|
|
41
|
+
IconMoon,
|
|
42
|
+
IconPanelRight,
|
|
43
|
+
IconPerson,
|
|
44
|
+
IconPlayCircle,
|
|
45
|
+
IconPlus,
|
|
46
|
+
IconPremium,
|
|
47
|
+
IconQueryEditor,
|
|
48
|
+
IconRadar,
|
|
49
|
+
IconRecording,
|
|
50
|
+
IconRobot,
|
|
51
|
+
IconRocket,
|
|
52
|
+
IconSave,
|
|
53
|
+
IconSearch,
|
|
54
|
+
IconSelectEvents,
|
|
55
|
+
IconStar,
|
|
56
|
+
IconSubArrowRight,
|
|
57
|
+
IconSun,
|
|
58
|
+
IconSurveys,
|
|
59
|
+
IconSync,
|
|
60
|
+
IconTableChart,
|
|
61
|
+
IconTerminal,
|
|
62
|
+
IconToggle,
|
|
63
|
+
IconTrash,
|
|
64
|
+
IconTuning,
|
|
65
|
+
IconUpload,
|
|
66
|
+
IconVolume,
|
|
67
|
+
IconVolumeOff,
|
|
68
|
+
PH_ICONS,
|
|
69
|
+
type IconName,
|
|
70
|
+
} from "@/components/icons";
|
|
71
|
+
import { ShowcaseWrapper } from "@/components/ui";
|
|
72
|
+
|
|
73
|
+
const iconCells: { name: IconName; Icon: (typeof PH_ICONS)[IconName] }[] = [
|
|
74
|
+
{ name: "activity", Icon: IconActivity },
|
|
75
|
+
{ name: "areaChart", Icon: IconAreaChart },
|
|
76
|
+
{ name: "arrowUp", Icon: IconArrowUp },
|
|
77
|
+
{ name: "arrowDown", Icon: IconArrowDown },
|
|
78
|
+
{ name: "bell", Icon: IconBell },
|
|
79
|
+
{ name: "bellOff", Icon: IconBellOff },
|
|
80
|
+
{ name: "bolt", Icon: IconBolt },
|
|
81
|
+
{ name: "box", Icon: IconBox },
|
|
82
|
+
{ name: "cancel", Icon: IconCancel },
|
|
83
|
+
{ name: "check", Icon: IconCheck },
|
|
84
|
+
{ name: "checkCircle", Icon: IconCheckCircle },
|
|
85
|
+
{ name: "chevronDown", Icon: IconChevronDown },
|
|
86
|
+
{ name: "chevronLeft", Icon: IconChevronLeft },
|
|
87
|
+
{ name: "chevronRight", Icon: IconChevronRight },
|
|
88
|
+
{ name: "clipboard", Icon: IconClipboardEdit },
|
|
89
|
+
{ name: "close", Icon: IconClose },
|
|
90
|
+
{ name: "cohort", Icon: IconCohort },
|
|
91
|
+
{ name: "copy", Icon: IconCopy },
|
|
92
|
+
{ name: "cumulativeChart", Icon: IconCumulativeChart },
|
|
93
|
+
{ name: "database", Icon: IconDatabase },
|
|
94
|
+
{ name: "download", Icon: IconDownload },
|
|
95
|
+
{ name: "edit", Icon: IconEdit },
|
|
96
|
+
{ name: "errorOutline", Icon: IconErrorOutline },
|
|
97
|
+
{ name: "exclamation", Icon: IconExclamation },
|
|
98
|
+
{ name: "flag", Icon: IconFlag },
|
|
99
|
+
{ name: "flare", Icon: IconFlare },
|
|
100
|
+
{ name: "flask", Icon: IconFlask },
|
|
101
|
+
{ name: "gift", Icon: IconGift },
|
|
102
|
+
{ name: "grid", Icon: IconGridView },
|
|
103
|
+
{ name: "handClick", Icon: IconHandClick },
|
|
104
|
+
{ name: "home", Icon: IconHome },
|
|
105
|
+
{ name: "layers", Icon: IconLayers },
|
|
106
|
+
{ name: "list", Icon: IconListView },
|
|
107
|
+
{ name: "logout", Icon: IconLogout },
|
|
108
|
+
{ name: "mail", Icon: IconMail },
|
|
109
|
+
{ name: "moon", Icon: IconMoon },
|
|
110
|
+
{ name: "panelRight", Icon: IconPanelRight },
|
|
111
|
+
{ name: "person", Icon: IconPerson },
|
|
112
|
+
{ name: "play", Icon: IconPlayCircle },
|
|
113
|
+
{ name: "plus", Icon: IconPlus },
|
|
114
|
+
{ name: "premium", Icon: IconPremium },
|
|
115
|
+
{ name: "queryEditor", Icon: IconQueryEditor },
|
|
116
|
+
{ name: "radar", Icon: IconRadar },
|
|
117
|
+
{ name: "recording", Icon: IconRecording },
|
|
118
|
+
{ name: "robot", Icon: IconRobot },
|
|
119
|
+
{ name: "rocket", Icon: IconRocket },
|
|
120
|
+
{ name: "save", Icon: IconSave },
|
|
121
|
+
{ name: "search", Icon: IconSearch },
|
|
122
|
+
{ name: "selectEvents", Icon: IconSelectEvents },
|
|
123
|
+
{ name: "settings", Icon: IconTuning },
|
|
124
|
+
{ name: "star", Icon: IconStar },
|
|
125
|
+
{ name: "subArrowRight", Icon: IconSubArrowRight },
|
|
126
|
+
{ name: "sun", Icon: IconSun },
|
|
127
|
+
{ name: "surveys", Icon: IconSurveys },
|
|
128
|
+
{ name: "sync", Icon: IconSync },
|
|
129
|
+
{ name: "tableChart", Icon: IconTableChart },
|
|
130
|
+
{ name: "terminal", Icon: IconTerminal },
|
|
131
|
+
{ name: "toggle", Icon: IconToggle },
|
|
132
|
+
{ name: "trash", Icon: IconTrash },
|
|
133
|
+
{ name: "upload", Icon: IconUpload },
|
|
134
|
+
{ name: "volume", Icon: IconVolume },
|
|
135
|
+
{ name: "volumeOff", Icon: IconVolumeOff },
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
const colourTiles = [
|
|
139
|
+
{ label: "Session replay", Icon: IconRecording, fg: "--ph-product-session-replay" as const },
|
|
140
|
+
{ label: "Product analytics", Icon: IconAreaChart, fg: "--ph-product-product-analytics" as const },
|
|
141
|
+
{ label: "Data pipeline", Icon: IconGridView, fg: "--ph-product-data-pipeline" as const },
|
|
142
|
+
{ label: "Feature flags", Icon: IconFlag, fg: "--ph-product-feature-flags" as const },
|
|
143
|
+
{ label: "Experiments", Icon: IconFlask, fg: "--ph-product-experiments" as const },
|
|
144
|
+
{ label: "Data warehouse", Icon: IconDatabase, fg: "--ph-product-data-warehouse" as const },
|
|
145
|
+
{ label: "Surveys", Icon: IconSurveys, fg: "--ph-product-surveys" as const },
|
|
146
|
+
];
|
|
147
|
+
|
|
148
|
+
export default function IconShowcase() {
|
|
149
|
+
const code = `import { IconActivity, IconAreaChart, IconArrowDown, IconArrowUp, IconBell, IconBellOff, IconBolt, IconBox, IconCancel, IconCheck, IconCheckCircle, IconChevronDown, IconChevronLeft, IconChevronRight, IconClipboardEdit, IconClose, IconCohort, IconCopy, IconCumulativeChart, IconDatabase, IconDownload, IconEdit, IconErrorOutline, IconExclamation, IconFlag, IconFlare, IconFlask, IconGift, IconGridView, IconHandClick, IconHome, IconLayers, IconListView, IconLogout, IconMail, IconMoon, IconPanelRight, IconPerson, IconPlayCircle, IconPlus, IconPremium, IconQueryEditor, IconRadar, IconRecording, IconRobot, IconRocket, IconSave, IconSearch, IconSelectEvents, IconStar, IconSubArrowRight, IconSun, IconSurveys, IconSync, IconTableChart, IconTerminal, IconToggle, IconTrash, IconTuning, IconUpload, IconVolume, IconVolumeOff, PH_ICONS, type IconName } from "the-old-ui";
|
|
150
|
+
|
|
151
|
+
<div className="space-y-8">
|
|
152
|
+
<div className="ph-panel space-y-4">
|
|
153
|
+
<h3 className="text-xs font-semibold uppercase tracking-wider text-ph-mutedtext">Bespoke Lemon glyphs</h3>
|
|
154
|
+
<p className="text-sm leading-relaxed text-ph-subtle">
|
|
155
|
+
Paths mirror PostHog's Lemon UI — filled{" "}
|
|
156
|
+
<code className="ph-kbd">currentColor</code> SVGs at <code className="ph-kbd">1em</code>, vendored in{" "}
|
|
157
|
+
<code className="ph-kbd">the-old-ui</code> (no Lucide).
|
|
158
|
+
</p>
|
|
159
|
+
|
|
160
|
+
<div className="grid grid-cols-3 gap-3 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8">
|
|
161
|
+
{iconCells.map(({ name, Icon }) => (
|
|
162
|
+
<div
|
|
163
|
+
key={name}
|
|
164
|
+
className="flex flex-col items-center gap-2 rounded-[var(--ph-radius-app)] border border-ph-border bg-ph-surface p-4 text-center"
|
|
165
|
+
style={{ boxShadow: "var(--ph-shadow-elevation-3000)" }}
|
|
166
|
+
>
|
|
167
|
+
<Icon className="h-6 w-6 text-ph-ink" />
|
|
168
|
+
<span className="text-[10px] font-medium uppercase tracking-wide text-ph-mutedtext">{name}</span>
|
|
169
|
+
</div>
|
|
170
|
+
))}
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
|
|
174
|
+
<div className="ph-panel space-y-4">
|
|
175
|
+
<h3 className="text-xs font-semibold uppercase tracking-wider text-ph-mutedtext">Product rail hues</h3>
|
|
176
|
+
<p className="text-sm leading-relaxed text-ph-subtle">
|
|
177
|
+
In-app nav tiles use saturated backgrounds with light glyphs — tokens map to{" "}
|
|
178
|
+
<code className="ph-kbd">--ph-product-*</code> in <code className="ph-kbd">globals.css</code>.
|
|
179
|
+
</p>
|
|
180
|
+
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-7">
|
|
181
|
+
{colourTiles.map(({ label, Icon, fg }) => (
|
|
182
|
+
<div
|
|
183
|
+
key={label}
|
|
184
|
+
className="ph-icon-tile border-white/15 text-white"
|
|
185
|
+
style={{ backgroundColor: \`var(\${fg})\` }}
|
|
186
|
+
>
|
|
187
|
+
<Icon className="mb-1 h-7 w-7 drop-shadow-sm" />
|
|
188
|
+
<span className="max-w-full truncate px-1 text-center normal-case tracking-normal">{label}</span>
|
|
189
|
+
</div>
|
|
190
|
+
))}
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>`;
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<ShowcaseWrapper
|
|
197
|
+
title="Icons"
|
|
198
|
+
description="Bespoke Lemon glyphs from PostHog open source — filled Material / product paths, not Lucide stroke icons."
|
|
199
|
+
code={code}
|
|
200
|
+
filename="IconExample.tsx"
|
|
201
|
+
>
|
|
202
|
+
<div className="space-y-8">
|
|
203
|
+
<div className="ph-panel space-y-4">
|
|
204
|
+
<h3 className="text-xs font-semibold uppercase tracking-wider text-ph-mutedtext">Bespoke Lemon glyphs</h3>
|
|
205
|
+
<p className="text-sm leading-relaxed text-ph-subtle">
|
|
206
|
+
Paths mirror PostHog's Lemon UI — filled{" "}
|
|
207
|
+
<code className="ph-kbd">currentColor</code> SVGs at <code className="ph-kbd">1em</code>, vendored in{" "}
|
|
208
|
+
<code className="ph-kbd">the-old-ui</code> (no Lucide).
|
|
209
|
+
</p>
|
|
210
|
+
|
|
211
|
+
<div className="grid grid-cols-3 gap-3 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8">
|
|
212
|
+
{iconCells.map(({ name, Icon }) => (
|
|
213
|
+
<div
|
|
214
|
+
key={name}
|
|
215
|
+
className="flex flex-col items-center gap-2 rounded-[var(--ph-radius-app)] border border-ph-border bg-ph-surface p-4 text-center"
|
|
216
|
+
style={{ boxShadow: "var(--ph-shadow-elevation-3000)" }}
|
|
217
|
+
>
|
|
218
|
+
<Icon className="h-6 w-6 text-ph-ink" />
|
|
219
|
+
<span className="text-[10px] font-medium uppercase tracking-wide text-ph-mutedtext">{name}</span>
|
|
220
|
+
</div>
|
|
221
|
+
))}
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
|
|
225
|
+
<div className="ph-panel space-y-4">
|
|
226
|
+
<h3 className="text-xs font-semibold uppercase tracking-wider text-ph-mutedtext">Product rail hues</h3>
|
|
227
|
+
<p className="text-sm leading-relaxed text-ph-subtle">
|
|
228
|
+
In-app nav tiles use saturated backgrounds with light glyphs — tokens map to{" "}
|
|
229
|
+
<code className="ph-kbd">--ph-product-*</code> in <code className="ph-kbd">globals.css</code>.
|
|
230
|
+
</p>
|
|
231
|
+
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-7">
|
|
232
|
+
{colourTiles.map(({ label, Icon, fg }) => (
|
|
233
|
+
<div
|
|
234
|
+
key={label}
|
|
235
|
+
className="ph-icon-tile border-white/15 text-white"
|
|
236
|
+
style={{ backgroundColor: `var(${fg})` }}
|
|
237
|
+
>
|
|
238
|
+
<Icon className="mb-1 h-7 w-7 drop-shadow-sm" />
|
|
239
|
+
<span className="max-w-full truncate px-1 text-center normal-case tracking-normal">{label}</span>
|
|
240
|
+
</div>
|
|
241
|
+
))}
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
</ShowcaseWrapper>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IconBell, IconMail, IconShoppingCart, IconSurveys } from "@/components/icons";
|
|
2
|
+
import { ComponentDocs, Indicator, ShowcaseWrapper } from "@/components/ui";
|
|
3
|
+
|
|
4
|
+
const indicators = [
|
|
5
|
+
{ icon: IconBell, label: "Notifications", count: "8", hue: "bg-ph-brand" },
|
|
6
|
+
{ icon: IconMail, label: "Messages", count: "99+", hue: "bg-ph-blue" },
|
|
7
|
+
{ icon: IconSurveys, label: "Comments", count: "3", hue: "bg-emerald-600" },
|
|
8
|
+
{ icon: IconShoppingCart, label: "Cart", count: "!", hue: "bg-ph-danger" },
|
|
9
|
+
] as const;
|
|
10
|
+
|
|
11
|
+
export default function IndicatorShowcase() {
|
|
12
|
+
const code = `import { Indicator } from "the-old-ui";
|
|
13
|
+
|
|
14
|
+
<Indicator badge="8" color="bg-ph-brand">
|
|
15
|
+
<Button variant="ghost" shape="circle">
|
|
16
|
+
<IconBell className="h-6 w-6" />
|
|
17
|
+
</Button>
|
|
18
|
+
</Indicator>
|
|
19
|
+
|
|
20
|
+
<Indicator dot color="bg-ph-brand">
|
|
21
|
+
<Avatar label="JD" />
|
|
22
|
+
</Indicator>`;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<ShowcaseWrapper
|
|
26
|
+
title="Badge hotspots"
|
|
27
|
+
description="Indicator badges and dots for notifications, status, and counts."
|
|
28
|
+
code={code}
|
|
29
|
+
filename="IndicatorExample.tsx"
|
|
30
|
+
docs={
|
|
31
|
+
<ComponentDocs
|
|
32
|
+
rows={[
|
|
33
|
+
{ name: "badge", type: "ReactNode", description: "Badge content (number, text, !)." },
|
|
34
|
+
{ name: "color", type: "string", defaultValue: "bg-ph-brand", description: "Tailwind colour class." },
|
|
35
|
+
{ name: "position", type: "top-right | top-left | bottom-right | bottom-left", defaultValue: "top-right", description: "Indicator position." },
|
|
36
|
+
{ name: "dot", type: "boolean", defaultValue: "false", description: "Show a simple dot instead of badge." },
|
|
37
|
+
]}
|
|
38
|
+
/>
|
|
39
|
+
}
|
|
40
|
+
>
|
|
41
|
+
<div className="flex flex-wrap gap-10 rounded-xl border border-ph-border bg-ph-muted px-10 py-8">
|
|
42
|
+
{indicators.map(({ icon: Icon, label, count, hue }) => (
|
|
43
|
+
<Indicator key={label} badge={count} color={hue}>
|
|
44
|
+
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-ph-surface shadow-ph">
|
|
45
|
+
<Icon className="h-6 w-6 text-ph-mutedtext" />
|
|
46
|
+
</div>
|
|
47
|
+
</Indicator>
|
|
48
|
+
))}
|
|
49
|
+
</div>
|
|
50
|
+
</ShowcaseWrapper>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Kbd, Panel, ShowcaseWrapper } from "@/components/ui";
|
|
2
|
+
|
|
3
|
+
export default function KbdShowcase() {
|
|
4
|
+
const code = `import { Kbd, Panel } from "the-old-ui";
|
|
5
|
+
|
|
6
|
+
<Panel className="flex flex-wrap items-center gap-3 text-ph-subtle">
|
|
7
|
+
<Kbd keys={["⌘", "K"]} />
|
|
8
|
+
<span className="text-xs font-semibold text-ph-mutedtext">/</span>
|
|
9
|
+
<Kbd keys={["⌥", "⇧", "E"]} />
|
|
10
|
+
<span className="text-xs font-semibold text-ph-mutedtext">/</span>
|
|
11
|
+
<Kbd variant="token">HogQL</Kbd>
|
|
12
|
+
<p className="w-full pt-5 text-xs text-ph-mutedtext">
|
|
13
|
+
Keyboard hints and code tokens are rendered through the same reusable component.
|
|
14
|
+
</p>
|
|
15
|
+
</Panel>`;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<ShowcaseWrapper title="Keyboard glyphs" code={code} filename="KbdExample.tsx">
|
|
19
|
+
<Panel className="flex flex-wrap items-center gap-3 text-ph-subtle">
|
|
20
|
+
<Kbd keys={["⌘", "K"]} />
|
|
21
|
+
<span className="text-xs font-semibold text-ph-mutedtext">/</span>
|
|
22
|
+
<Kbd keys={["⌥", "⇧", "E"]} />
|
|
23
|
+
<span className="text-xs font-semibold text-ph-mutedtext">/</span>
|
|
24
|
+
<Kbd variant="token">HogQL</Kbd>
|
|
25
|
+
<p className="w-full pt-5 text-xs text-ph-mutedtext">
|
|
26
|
+
Keyboard hints and code tokens are rendered through the same reusable component.
|
|
27
|
+
</p>
|
|
28
|
+
</Panel>
|
|
29
|
+
</ShowcaseWrapper>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { IconCheck, IconClose, IconPlus } from "@/components/icons";
|
|
5
|
+
import { Button, ComponentDocs, Input, Modal, Select, ShowcaseWrapper, Textarea } from "@/components/ui";
|
|
6
|
+
|
|
7
|
+
export default function ModalShowcase() {
|
|
8
|
+
const [openModal, setOpenModal] = useState<string | null>(null);
|
|
9
|
+
|
|
10
|
+
const close = () => setOpenModal(null);
|
|
11
|
+
|
|
12
|
+
const code = `import { IconCheck, IconClose, IconPlus } from "the-old-ui";
|
|
13
|
+
import { Button, Input, Modal, Select, Textarea } from "the-old-ui";
|
|
14
|
+
|
|
15
|
+
<div className="ph-panel space-y-4">
|
|
16
|
+
<h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Patterns</h3>
|
|
17
|
+
|
|
18
|
+
<div className="flex flex-wrap gap-3">
|
|
19
|
+
<Button variant="secondary" onClick={() => setOpenModal("info")}>
|
|
20
|
+
Info
|
|
21
|
+
</Button>
|
|
22
|
+
<Button variant="success" onClick={() => setOpenModal("success")}>
|
|
23
|
+
Success
|
|
24
|
+
</Button>
|
|
25
|
+
<Button variant="danger" onClick={() => setOpenModal("error")}>
|
|
26
|
+
Error
|
|
27
|
+
</Button>
|
|
28
|
+
<Button variant="primary" icon={<IconPlus className="h-4 w-4" aria-hidden />} onClick={() => setOpenModal("form")}>
|
|
29
|
+
Form modal
|
|
30
|
+
</Button>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<Modal
|
|
34
|
+
open={openModal === "info"}
|
|
35
|
+
onClose={close}
|
|
36
|
+
title="Configure capture"
|
|
37
|
+
description="Lightweight overlay + white sheet — Lemon modals skew toward tight copy and decisive buttons."
|
|
38
|
+
footer={<Button variant="secondary" onClick={close}>Close</Button>}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
<Modal
|
|
42
|
+
open={openModal === "success"}
|
|
43
|
+
onClose={close}
|
|
44
|
+
showCloseButton={false}
|
|
45
|
+
footer={<Button variant="success" onClick={close}>Continue</Button>}
|
|
46
|
+
>
|
|
47
|
+
<div className="flex items-start gap-3">
|
|
48
|
+
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-ph-success">
|
|
49
|
+
<IconCheck className="h-5 w-5" />
|
|
50
|
+
</div>
|
|
51
|
+
<div>
|
|
52
|
+
<h3 className="text-lg font-bold text-ph-success">Saved</h3>
|
|
53
|
+
<p className="mt-1 text-sm text-ph-subtle">Your dashboard layout synced to the team.</p>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</Modal>
|
|
57
|
+
|
|
58
|
+
<Modal
|
|
59
|
+
open={openModal === "error"}
|
|
60
|
+
onClose={close}
|
|
61
|
+
showCloseButton={false}
|
|
62
|
+
footer={
|
|
63
|
+
<>
|
|
64
|
+
<Button variant="ghost" onClick={close}>Cancel</Button>
|
|
65
|
+
<Button variant="danger" onClick={close}>View logs</Button>
|
|
66
|
+
</>
|
|
67
|
+
}
|
|
68
|
+
>
|
|
69
|
+
<div className="flex items-start gap-3">
|
|
70
|
+
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-red-100 text-ph-danger">
|
|
71
|
+
<IconClose className="h-5 w-5" />
|
|
72
|
+
</div>
|
|
73
|
+
<div>
|
|
74
|
+
<h3 className="text-lg font-bold text-ph-danger">Query failed</h3>
|
|
75
|
+
<p className="mt-1 text-sm text-ph-subtle">ClickHouse returned a timeout — retry or narrow the date range.</p>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</Modal>
|
|
79
|
+
|
|
80
|
+
<Modal
|
|
81
|
+
open={openModal === "form"}
|
|
82
|
+
onClose={close}
|
|
83
|
+
size="lg"
|
|
84
|
+
title="Create feature flag"
|
|
85
|
+
footer={
|
|
86
|
+
<>
|
|
87
|
+
<Button variant="ghost" onClick={close}>Cancel</Button>
|
|
88
|
+
<Button variant="primary" onClick={close}>Create</Button>
|
|
89
|
+
</>
|
|
90
|
+
}
|
|
91
|
+
>
|
|
92
|
+
<div className="space-y-4">
|
|
93
|
+
<Input label="Key" placeholder="billing-ui-v3" />
|
|
94
|
+
<Textarea label="Description" placeholder="Expose the rewritten billing funnel" className="h-28" />
|
|
95
|
+
<Select label="Rollout">
|
|
96
|
+
<option>10% staged</option>
|
|
97
|
+
<option>Everyone</option>
|
|
98
|
+
</Select>
|
|
99
|
+
</div>
|
|
100
|
+
</Modal>
|
|
101
|
+
</div>`;
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<ShowcaseWrapper
|
|
105
|
+
title="Modals"
|
|
106
|
+
description="Accessible modal shell with open state, title, description, size, close button, and footer props."
|
|
107
|
+
code={code}
|
|
108
|
+
filename="ModalExample.tsx"
|
|
109
|
+
docs={
|
|
110
|
+
<ComponentDocs
|
|
111
|
+
rows={[
|
|
112
|
+
{ name: "open", type: "boolean", defaultValue: "false", description: "Controls modal visibility." },
|
|
113
|
+
{ name: "onClose", type: "() => void", description: "Called by overlay and close button." },
|
|
114
|
+
{ name: "size", type: "sm | md | lg | xl | full", defaultValue: "md", description: "Controls panel max width." },
|
|
115
|
+
{ name: "title", type: "string", description: "Accessible dialog heading." },
|
|
116
|
+
{ name: "footer", type: "ReactNode", description: "Renders action row with consistent spacing." },
|
|
117
|
+
]}
|
|
118
|
+
/>
|
|
119
|
+
}
|
|
120
|
+
>
|
|
121
|
+
<div className="ph-panel space-y-4">
|
|
122
|
+
<h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Patterns</h3>
|
|
123
|
+
|
|
124
|
+
<div className="flex flex-wrap gap-3">
|
|
125
|
+
<Button variant="secondary" onClick={() => setOpenModal("info")}>
|
|
126
|
+
Info
|
|
127
|
+
</Button>
|
|
128
|
+
<Button variant="success" onClick={() => setOpenModal("success")}>
|
|
129
|
+
Success
|
|
130
|
+
</Button>
|
|
131
|
+
<Button variant="danger" onClick={() => setOpenModal("error")}>
|
|
132
|
+
Error
|
|
133
|
+
</Button>
|
|
134
|
+
<Button variant="primary" icon={<IconPlus className="h-4 w-4" aria-hidden />} onClick={() => setOpenModal("form")}>
|
|
135
|
+
Form modal
|
|
136
|
+
</Button>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<Modal
|
|
140
|
+
open={openModal === "info"}
|
|
141
|
+
onClose={close}
|
|
142
|
+
title="Configure capture"
|
|
143
|
+
description="Lightweight overlay + white sheet — Lemon modals skew toward tight copy and decisive buttons."
|
|
144
|
+
footer={<Button variant="secondary" onClick={close}>Close</Button>}
|
|
145
|
+
/>
|
|
146
|
+
|
|
147
|
+
<Modal
|
|
148
|
+
open={openModal === "success"}
|
|
149
|
+
onClose={close}
|
|
150
|
+
showCloseButton={false}
|
|
151
|
+
footer={<Button variant="success" onClick={close}>Continue</Button>}
|
|
152
|
+
>
|
|
153
|
+
<div className="flex items-start gap-3">
|
|
154
|
+
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-ph-success">
|
|
155
|
+
<IconCheck className="h-5 w-5" />
|
|
156
|
+
</div>
|
|
157
|
+
<div>
|
|
158
|
+
<h3 className="text-lg font-bold text-ph-success">Saved</h3>
|
|
159
|
+
<p className="mt-1 text-sm text-ph-subtle">Your dashboard layout synced to the team.</p>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
</Modal>
|
|
163
|
+
|
|
164
|
+
<Modal
|
|
165
|
+
open={openModal === "error"}
|
|
166
|
+
onClose={close}
|
|
167
|
+
showCloseButton={false}
|
|
168
|
+
footer={
|
|
169
|
+
<>
|
|
170
|
+
<Button variant="ghost" onClick={close}>Cancel</Button>
|
|
171
|
+
<Button variant="danger" onClick={close}>View logs</Button>
|
|
172
|
+
</>
|
|
173
|
+
}
|
|
174
|
+
>
|
|
175
|
+
<div className="flex items-start gap-3">
|
|
176
|
+
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-red-100 text-ph-danger">
|
|
177
|
+
<IconClose className="h-5 w-5" />
|
|
178
|
+
</div>
|
|
179
|
+
<div>
|
|
180
|
+
<h3 className="text-lg font-bold text-ph-danger">Query failed</h3>
|
|
181
|
+
<p className="mt-1 text-sm text-ph-subtle">ClickHouse returned a timeout — retry or narrow the date range.</p>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</Modal>
|
|
185
|
+
|
|
186
|
+
<Modal
|
|
187
|
+
open={openModal === "form"}
|
|
188
|
+
onClose={close}
|
|
189
|
+
size="lg"
|
|
190
|
+
title="Create feature flag"
|
|
191
|
+
footer={
|
|
192
|
+
<>
|
|
193
|
+
<Button variant="ghost" onClick={close}>Cancel</Button>
|
|
194
|
+
<Button variant="primary" onClick={close}>Create</Button>
|
|
195
|
+
</>
|
|
196
|
+
}
|
|
197
|
+
>
|
|
198
|
+
<div className="space-y-4">
|
|
199
|
+
<Input label="Key" placeholder="billing-ui-v3" />
|
|
200
|
+
<Textarea label="Description" placeholder="Expose the rewritten billing funnel" className="h-28" />
|
|
201
|
+
<Select label="Rollout">
|
|
202
|
+
<option>10% staged</option>
|
|
203
|
+
<option>Everyone</option>
|
|
204
|
+
</Select>
|
|
205
|
+
</div>
|
|
206
|
+
</Modal>
|
|
207
|
+
</div>
|
|
208
|
+
</ShowcaseWrapper>
|
|
209
|
+
);
|
|
210
|
+
}
|