@xenide-io/the-old-ui-theme 0.4.4 → 0.4.8

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.
Files changed (76) hide show
  1. package/dist/{chunk-54ZR4VL5.mjs → chunk-RZXHZWUB.mjs} +44 -17
  2. package/dist/{index-B5NOyoKS.d.mts → index-Od4pIP4F.d.mts} +7 -1
  3. package/dist/{index-B5NOyoKS.d.ts → index-Od4pIP4F.d.ts} +7 -1
  4. package/dist/index.d.mts +2 -2
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +37 -10
  7. package/dist/index.mjs +1 -1
  8. package/dist/suite.d.mts +152 -41
  9. package/dist/suite.d.ts +152 -41
  10. package/dist/suite.js +1366 -671
  11. package/dist/suite.mjs +1304 -610
  12. package/dist/ui.d.mts +1 -1
  13. package/dist/ui.d.ts +1 -1
  14. package/dist/ui.js +37 -10
  15. package/dist/ui.mjs +1 -1
  16. package/package.json +7 -3
  17. package/src/components/ui/Modal.tsx +70 -26
  18. package/src/styles/suite-skin.css +284 -24
  19. package/src/suite/components/ai-panel.test.ts +20 -0
  20. package/src/suite/components/ai-panel.tsx +494 -103
  21. package/src/suite/components/suite-app-layout.tsx +48 -28
  22. package/src/suite/components/suite-layout.tsx +84 -40
  23. package/src/suite/components/suite-mobile-drawer.tsx +35 -22
  24. package/src/suite/components/suite-notification-bell.tsx +9 -3
  25. package/src/suite/components/suite-settings-layout.tsx +82 -0
  26. package/src/suite/components/suite-settings-mobile-nav.tsx +18 -17
  27. package/src/suite/components/suite-skeleton.tsx +3 -3
  28. package/src/suite/components/today-calibrating.tsx +11 -35
  29. package/src/suite/components/today-page-frame.tsx +19 -11
  30. package/src/suite/components/today-ui.tsx +276 -19
  31. package/src/suite/index.ts +41 -25
  32. package/src/suite/lib/apps.ts +32 -2
  33. package/src/suite/lib/use-sidebar-width.ts +114 -0
  34. package/src/components/sections/AccordionShowcase.tsx +0 -45
  35. package/src/components/sections/AlertShowcase.tsx +0 -40
  36. package/src/components/sections/AvatarShowcase.tsx +0 -80
  37. package/src/components/sections/BadgeShowcase.tsx +0 -65
  38. package/src/components/sections/ButtonShowcase.tsx +0 -308
  39. package/src/components/sections/CalendarShowcase.tsx +0 -35
  40. package/src/components/sections/CardShowcase.tsx +0 -159
  41. package/src/components/sections/CodeMockupShowcase.tsx +0 -56
  42. package/src/components/sections/ColorPalette.tsx +0 -117
  43. package/src/components/sections/CommandPaletteShowcase.tsx +0 -48
  44. package/src/components/sections/CountdownShowcase.tsx +0 -43
  45. package/src/components/sections/DiffShowcase.tsx +0 -70
  46. package/src/components/sections/DrawerShowcase.tsx +0 -97
  47. package/src/components/sections/DropdownShowcase.tsx +0 -98
  48. package/src/components/sections/EmptyStateShowcase.tsx +0 -50
  49. package/src/components/sections/FilterChipsShowcase.tsx +0 -98
  50. package/src/components/sections/FormShowcase.tsx +0 -127
  51. package/src/components/sections/HoverCardShowcase.tsx +0 -50
  52. package/src/components/sections/IconShowcase.tsx +0 -121
  53. package/src/components/sections/IndicatorShowcase.tsx +0 -52
  54. package/src/components/sections/KbdShowcase.tsx +0 -57
  55. package/src/components/sections/ModalShowcase.tsx +0 -211
  56. package/src/components/sections/NavigationShowcase.tsx +0 -199
  57. package/src/components/sections/NewComponentsShowcase.tsx +0 -1052
  58. package/src/components/sections/ProductLayoutsShowcase.tsx +0 -78
  59. package/src/components/sections/ProgressShowcase.tsx +0 -82
  60. package/src/components/sections/QuillChartShowcase.tsx +0 -92
  61. package/src/components/sections/QuillDashboardShowcase.tsx +0 -149
  62. package/src/components/sections/SegmentedControlShowcase.tsx +0 -49
  63. package/src/components/sections/SetupThemeShowcase.tsx +0 -262
  64. package/src/components/sections/SidebarShowcase.tsx +0 -152
  65. package/src/components/sections/StackShowcase.tsx +0 -33
  66. package/src/components/sections/StepperShowcase.tsx +0 -37
  67. package/src/components/sections/SuiteShowcase.tsx +0 -669
  68. package/src/components/sections/SwapShowcase.tsx +0 -99
  69. package/src/components/sections/TabShowcase.tsx +0 -84
  70. package/src/components/sections/TableShowcase.tsx +0 -142
  71. package/src/components/sections/TimelineShowcase.tsx +0 -83
  72. package/src/components/sections/ToastShowcase.tsx +0 -108
  73. package/src/components/sections/TooltipShowcase.tsx +0 -38
  74. package/src/components/sections/UtilityShowcase.tsx +0 -81
  75. package/src/styles/excel-themes.css +0 -110
  76. package/src/styles/lemon-primitives.css +0 -550
@@ -1,99 +0,0 @@
1
- "use client";
2
-
3
- import { IconBell, IconBellOff, IconMoon, IconSun, IconVolume, IconVolumeOff } from "@/components/icons";
4
- import { cn } from "@/lib/cn";
5
- import { ShowcaseWrapper } from "@/components/ui";
6
-
7
- function IconSwapToggle({
8
- offIcon: OffIcon,
9
- onIcon: OnIcon,
10
- offClassName,
11
- onClassName,
12
- label,
13
- }: {
14
- offIcon: typeof IconBellOff;
15
- onIcon: typeof IconBell;
16
- offClassName?: string;
17
- onClassName?: string;
18
- label: string;
19
- }) {
20
- return (
21
- <label className="group relative inline-flex h-14 w-14 cursor-pointer items-center justify-center rounded-full bg-ph-surface shadow-ph focus-within:ring-2 focus-within:ring-ph-focus focus-within:ring-offset-2">
22
- <input type="checkbox" className="sr-only" aria-label={label} />
23
- <span className="ph-icon-swap h-7 w-7" aria-hidden>
24
- <OffIcon
25
- className={cn(
26
- "opacity-100 transition group-has-[:checked]:pointer-events-none group-has-[:checked]:opacity-0",
27
- offClassName,
28
- )}
29
- />
30
- <OnIcon
31
- className={cn(
32
- "opacity-0 transition group-has-[:checked]:opacity-100",
33
- onClassName,
34
- )}
35
- />
36
- </span>
37
- </label>
38
- );
39
- }
40
-
41
- export default function SwapShowcase() {
42
- const code = `import { IconBell, IconBellOff, IconMoon, IconSun, IconVolume, IconVolumeOff } from "@xenide-io/the-old-ui-theme";
43
-
44
- <div className="flex flex-wrap gap-10 rounded-xl border border-ph-border bg-ph-muted p-8">
45
- <IconSwapToggle
46
- label="Mute audio"
47
- offIcon={IconVolume}
48
- onIcon={IconVolumeOff}
49
- offClassName="text-ph-brand"
50
- onClassName="text-ph-mutedtext"
51
- />
52
-
53
- <IconSwapToggle
54
- label="Mute notifications"
55
- offIcon={IconBell}
56
- onIcon={IconBellOff}
57
- offClassName="rotate-[-8deg] text-ph-mutedtext"
58
- onClassName="text-ph-mutedtext"
59
- />
60
-
61
- <IconSwapToggle
62
- label="Use light appearance"
63
- offIcon={IconMoon}
64
- onIcon={IconSun}
65
- offClassName="text-ph-mutedtext"
66
- onClassName="text-ph-warning"
67
- />
68
- </div>`;
69
-
70
- return (
71
- <ShowcaseWrapper title="Icon swap" code={code} filename="SwapExample.tsx">
72
- <div className="flex flex-wrap gap-10 rounded-xl border border-ph-border bg-ph-muted p-8">
73
- <IconSwapToggle
74
- label="Mute audio"
75
- offIcon={IconVolume}
76
- onIcon={IconVolumeOff}
77
- offClassName="text-ph-brand"
78
- onClassName="text-ph-mutedtext"
79
- />
80
-
81
- <IconSwapToggle
82
- label="Mute notifications"
83
- offIcon={IconBell}
84
- onIcon={IconBellOff}
85
- offClassName="rotate-[-8deg] text-ph-mutedtext"
86
- onClassName="text-ph-mutedtext"
87
- />
88
-
89
- <IconSwapToggle
90
- label="Use light appearance"
91
- offIcon={IconMoon}
92
- onIcon={IconSun}
93
- offClassName="text-ph-mutedtext"
94
- onClassName="text-ph-warning"
95
- />
96
- </div>
97
- </ShowcaseWrapper>
98
- );
99
- }
@@ -1,84 +0,0 @@
1
- "use client";
2
-
3
- import { useState } from "react";
4
- import { ComponentDocs, ShowcaseWrapper, Tabs } from "@/components/ui";
5
-
6
- const pillItems = [
7
- { value: "overview", label: "Overview" },
8
- { value: "activity", label: "Activity" },
9
- { value: "settings", label: "Settings" },
10
- ];
11
-
12
- const insightItems = [
13
- { value: "funnels", label: "Funnels" },
14
- { value: "trends", label: "Trends" },
15
- { value: "retention", label: "Retention" },
16
- ];
17
-
18
- const insightCopy: Record<string, string> = {
19
- funnels: "Step-through conversion diagnostics for each stage of your onboarding.",
20
- trends: "Arithmetic, formulas, breakdowns — the default insight landing state.",
21
- retention: "Cohort resurfacing curves with optional granularity controls.",
22
- };
23
-
24
- export default function TabShowcase() {
25
- const [pill, setPill] = useState("overview");
26
- const [insight, setInsight] = useState("funnels");
27
-
28
- const code = `import { Tabs } from "the-old-ui";
29
-
30
- <div className="grid gap-8 lg:grid-cols-2">
31
- <div className="ph-panel">
32
- <h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Floating pill track</h3>
33
- <Tabs items={pillItems} value={pill} onChange={setPill} />
34
- <p className="mt-6 text-sm text-ph-subtle">
35
- Mirrors the softly inset control groups from the product chrome — muted rail + white thumb.
36
- </p>
37
- </div>
38
-
39
- <div className="ph-panel space-y-4">
40
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Underline tabs</h3>
41
- <Tabs items={insightItems} value={insight} onChange={setInsight} variant="underline" />
42
- <div className="rounded-lg border border-ph-border bg-ph-surface p-5 shadow-ph">
43
- <p className="text-sm leading-relaxed text-ph-subtle">{insightCopy[insight]}</p>
44
- </div>
45
- </div>
46
- </div>`;
47
-
48
- return (
49
- <ShowcaseWrapper
50
- title="Tabs"
51
- description="Controlled tab primitive with pill and underline variants."
52
- code={code}
53
- filename="TabsExample.tsx"
54
- docs={
55
- <ComponentDocs
56
- rows={[
57
- { name: "items", type: "{ value; label }[]", description: "Tab labels and values." },
58
- { name: "value", type: "string", description: "Current tab value." },
59
- { name: "onChange", type: "(value: string) => void", description: "Called when a tab is selected." },
60
- { name: "variant", type: "pill | underline", defaultValue: "pill", description: "Visual tab style." },
61
- ]}
62
- />
63
- }
64
- >
65
- <div className="grid gap-8 lg:grid-cols-2">
66
- <div className="ph-panel">
67
- <h3 className="mb-4 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Floating pill track</h3>
68
- <Tabs items={pillItems} value={pill} onChange={setPill} />
69
- <p className="mt-6 text-sm text-ph-subtle">
70
- Mirrors the softly inset control groups from the product chrome — muted rail + white thumb.
71
- </p>
72
- </div>
73
-
74
- <div className="ph-panel space-y-4">
75
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Underline tabs</h3>
76
- <Tabs items={insightItems} value={insight} onChange={setInsight} variant="underline" />
77
- <div className="rounded-lg border border-ph-border bg-ph-surface p-5 shadow-ph">
78
- <p className="text-sm leading-relaxed text-ph-subtle">{insightCopy[insight]}</p>
79
- </div>
80
- </div>
81
- </div>
82
- </ShowcaseWrapper>
83
- );
84
- }
@@ -1,142 +0,0 @@
1
- "use client";
2
-
3
- import type { CSSProperties } from "react";
4
- import { Badge, ComponentDocs, ShowcaseWrapper, Table, type TableColumn } from "@/components/ui";
5
-
6
- const data = [
7
- { id: 1, name: "Alice Johnson", role: "Developer", status: "Active", plan: "Pro" },
8
- { id: 2, name: "Bob Smith", role: "Designer", status: "Offline", plan: "Basic" },
9
- { id: 3, name: "Charlie Brown", role: "Manager", status: "Active", plan: "Enterprise" },
10
- { id: 4, name: "Diana Prince", role: "Developer", status: "Busy", plan: "Pro" },
11
- { id: 5, name: "Eve Davis", role: "QA", status: "Active", plan: "Basic" },
12
- ];
13
-
14
- const ribbonByPlan: Record<string, string> = {
15
- Pro: "var(--ph-data-1)",
16
- Basic: "var(--ph-data-4)",
17
- Enterprise: "var(--ph-data-6)",
18
- };
19
-
20
- type UserRow = (typeof data)[number];
21
-
22
- const statusVariant: Record<string, "success" | "neutral" | "warning"> = {
23
- Active: "success",
24
- Offline: "neutral",
25
- Busy: "warning",
26
- };
27
-
28
- const columns: TableColumn<UserRow>[] = [
29
- { key: "id", header: "#", cell: (row) => <span className="tabular-nums text-ph-mutedtext">{row.id}</span>, className: "w-12 text-center" },
30
- { key: "name", header: "Name", cell: (row) => <span className="font-medium text-ph-ink">{row.name}</span> },
31
- { key: "role", header: "Role", cell: (row) => row.role },
32
- { key: "status", header: "Status", cell: (row) => <Badge variant={statusVariant[row.status] ?? "outline"}>{row.status}</Badge> },
33
- { key: "plan", header: "Plan", cell: (row) => <span className="text-ph-subtle">{row.plan}</span> },
34
- ];
35
-
36
- const keyValueData = [
37
- { key: "distinct_id", value: "019b2eef-..." },
38
- { key: "capture_api_version", value: "2024-06-06" },
39
- ];
40
-
41
- const keyValueColumns: TableColumn<(typeof keyValueData)[number]>[] = [
42
- { key: "key", header: "Key", cell: (row) => <span className="font-mono text-xs">{row.key}</span> },
43
- { key: "value", header: "Value", cell: (row) => <span className="font-mono text-xs">{row.value}</span> },
44
- ];
45
-
46
- export default function TableShowcase() {
47
- const code = `import { Badge, Table, type TableColumn } from "the-old-ui";
48
-
49
- <div className="space-y-8">
50
- <div>
51
- <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Dashboard table</h3>
52
- <p className="mb-4 max-w-2xl text-sm text-ph-subtle">
53
- White canvas, tinted header strip, zebra optional — avoids DaisyUI&apos;s chunky row chrome.
54
- </p>
55
- <Table data={data} columns={columns} caption="Dashboard users" />
56
- </div>
57
-
58
- <div>
59
- <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Ribbon column</h3>
60
- <p className="mb-4 max-w-2xl text-sm text-ph-subtle">
61
- Per-row accents via inherited <code className="ph-kbd">--row-ribbon</code> mimic Lemon insight list markers (
62
- <code className="ph-kbd">.ph-table--ribbon</code>).
63
- </p>
64
- <Table
65
- data={data}
66
- columns={columns}
67
- ribbon
68
- getRowStyle={(row) => ({
69
- "--row-ribbon": ribbonByPlan[row.plan] ?? "var(--ph-data-5)",
70
- } as CSSProperties)}
71
- />
72
- </div>
73
-
74
- <div>
75
- <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Zebra rows</h3>
76
- <Table data={data} columns={columns.slice(0, 4)} zebra />
77
- </div>
78
-
79
- <div>
80
- <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Compact density</h3>
81
- <Table data={keyValueData} columns={keyValueColumns} compact className="max-w-xl" />
82
- </div>
83
- </div>`;
84
-
85
- return (
86
- <ShowcaseWrapper
87
- title="Tables"
88
- description="Data table wrapper with typed columns, zebra rows, compact density, and component-based cell rendering."
89
- code={code}
90
- filename="TableExample.tsx"
91
- docs={
92
- <ComponentDocs
93
- rows={[
94
- { name: "data", type: "T[]", description: "Rows passed to each column cell renderer." },
95
- { name: "columns", type: "TableColumn<T>[]", description: "Column definitions with header and cell render function." },
96
- { name: "zebra", type: "boolean", defaultValue: "false", description: "Adds alternating row backgrounds." },
97
- { name: "compact", type: "boolean", defaultValue: "false", description: "Reduces density for admin tables." },
98
- { name: "ribbon", type: "boolean", defaultValue: "false", description: "Adds per-row accent ribbon support." },
99
- { name: "getRowStyle", type: "(row: T) => CSSProperties", description: "Optional row-level CSS variables or inline style." },
100
- { name: "caption", type: "string", description: "Accessible table caption rendered visually hidden." },
101
- ]}
102
- />
103
- }
104
- >
105
- <div className="space-y-8">
106
- <div>
107
- <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Dashboard table</h3>
108
- <p className="mb-4 max-w-2xl text-sm text-ph-subtle">
109
- White canvas, tinted header strip, zebra optional — avoids DaisyUI&apos;s chunky row chrome.
110
- </p>
111
- <Table data={data} columns={columns} caption="Dashboard users" />
112
- </div>
113
-
114
- <div>
115
- <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Ribbon column</h3>
116
- <p className="mb-4 max-w-2xl text-sm text-ph-subtle">
117
- Per-row accents via inherited <code className="ph-kbd">--row-ribbon</code> mimic Lemon insight list markers (
118
- <code className="ph-kbd">.ph-table--ribbon</code>).
119
- </p>
120
- <Table
121
- data={data}
122
- columns={columns}
123
- ribbon
124
- getRowStyle={(row) => ({
125
- "--row-ribbon": ribbonByPlan[row.plan] ?? "var(--ph-data-5)",
126
- } as CSSProperties)}
127
- />
128
- </div>
129
-
130
- <div>
131
- <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Zebra rows</h3>
132
- <Table data={data} columns={columns.slice(0, 4)} zebra />
133
- </div>
134
-
135
- <div>
136
- <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Compact density</h3>
137
- <Table data={keyValueData} columns={keyValueColumns} compact className="max-w-xl" />
138
- </div>
139
- </div>
140
- </ShowcaseWrapper>
141
- );
142
- }
@@ -1,83 +0,0 @@
1
- import { IconAreaChart, IconBolt, IconGift, IconRocket } from "@/components/icons";
2
- import { ComponentDocs, ShowcaseWrapper, Timeline } from "@/components/ui";
3
-
4
- const events = [
5
- {
6
- id: "1",
7
- icon: <IconRocket className="h-6 w-6" />,
8
- color: "bg-ph-brand text-white",
9
- title: "Project scaffolded",
10
- desc: "Next.js ingestion keys issued for prod + staging.",
11
- time: "2h ago",
12
- },
13
- {
14
- id: "2",
15
- icon: <IconBolt className="h-6 w-6" />,
16
- color: "bg-ph-purple text-white",
17
- title: "$pageview spikes",
18
- desc: "CDN edge experiment rolled to 42% cohort.",
19
- time: "1h ago",
20
- },
21
- {
22
- id: "3",
23
- icon: <IconAreaChart className="h-6 w-6" />,
24
- color: "bg-ph-blue text-white",
25
- title: "Dashboard shared",
26
- desc: "Growth pack pinned to Slack #metrics.",
27
- time: "45m ago",
28
- },
29
- {
30
- id: "4",
31
- icon: <IconGift className="h-6 w-6" />,
32
- color: "bg-emerald-600 text-white",
33
- title: "Feature flag LIVE",
34
- desc: "pricing-test-v3 now default for EU traffic.",
35
- time: "Just now",
36
- },
37
- ];
38
-
39
- export default function TimelineShowcase() {
40
- const code = `import { Timeline } from "the-old-ui";
41
-
42
- <Timeline
43
- events={[
44
- {
45
- id: "1",
46
- title: "Project scaffolded",
47
- description: "Keys issued for prod + staging.",
48
- time: "2h ago",
49
- icon: <IconRocket />,
50
- color: "bg-ph-brand text-white",
51
- },
52
- ]}
53
- alternate
54
- />`;
55
-
56
- return (
57
- <ShowcaseWrapper
58
- title="Timeline"
59
- description="Event timeline with icons, descriptions, and alternating layout."
60
- code={code}
61
- filename="TimelineExample.tsx"
62
- docs={
63
- <ComponentDocs
64
- rows={[
65
- { name: "events", type: "TimelineEvent[]", description: "Timeline events to render." },
66
- { name: "alternate", type: "boolean", defaultValue: "false", description: "Alternate left/right on large screens." },
67
- { name: "event.id", type: "string", description: "Unique key." },
68
- { name: "event.title", type: "string", description: "Event title." },
69
- { name: "event.description", type: "string", description: "Event description." },
70
- { name: "event.time", type: "string", description: "Timestamp." },
71
- { name: "event.icon", type: "ReactNode", description: "Icon element." },
72
- { name: "event.color", type: "string", description: "Tailwind colour classes." },
73
- ]}
74
- />
75
- }
76
- >
77
- <div className="relative ph-panel overflow-hidden">
78
- <div className="absolute bottom-8 left-[3.125rem] top-8 w-px bg-ph-border lg:left-[3.5rem]" aria-hidden />
79
- <Timeline events={events} alternate />
80
- </div>
81
- </ShowcaseWrapper>
82
- );
83
- }
@@ -1,108 +0,0 @@
1
- "use client";
2
-
3
- import { useState } from "react";
4
- import {
5
- ComponentDocs,
6
- Button,
7
- ShowcaseWrapper,
8
- Toast,
9
- ToastStack,
10
- } from "@/components/ui";
11
-
12
- const toasts = [
13
- {
14
- id: 1,
15
- status: "info" as const,
16
- title: "New deploy",
17
- text: "Warehouse sync node rotated without downtime.",
18
- },
19
- {
20
- id: 2,
21
- status: "success" as const,
22
- title: "Exports healthy",
23
- text: "Snowflake incremental finished in 41s.",
24
- },
25
- {
26
- id: 3,
27
- status: "warning" as const,
28
- title: "Approaching quota",
29
- text: "Session replay capture at 92% monthly allocation.",
30
- },
31
- {
32
- id: 4,
33
- status: "danger" as const,
34
- title: "Batch failed",
35
- text: "Stripe connector returned HTTP 524 — backing off.",
36
- },
37
- ];
38
-
39
- export default function ToastShowcase() {
40
- const [visible, setVisible] = useState<number[]>(toasts.map((t) => t.id));
41
-
42
- const code = `import { Button, Toast, ToastStack } from "the-old-ui";
43
-
44
- <div className="ph-panel">
45
- <div className="mb-4 flex items-center justify-between">
46
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Snack stack demo</h3>
47
- <Button variant="ghost" size="sm" onClick={() => setVisible(toasts.map((t) => t.id))}>
48
- Restore all
49
- </Button>
50
- </div>
51
- <ToastStack className="max-w-xl">
52
- {toasts.map((toast) => {
53
- if (!visible.includes(toast.id)) return null;
54
- return (
55
- <Toast
56
- key={toast.id}
57
- status={toast.status}
58
- title={toast.title}
59
- description={toast.text}
60
- onDismiss={() => setVisible((v) => v.filter((x) => x !== toast.id))}
61
- />
62
- );
63
- })}
64
- </ToastStack>
65
- </div>`;
66
-
67
- return (
68
- <ShowcaseWrapper
69
- title="Toasts"
70
- description="Snack stack notifications with semantic colour variants and dismiss actions."
71
- code={code}
72
- filename="ToastExample.tsx"
73
- docs={
74
- <ComponentDocs
75
- rows={[
76
- { name: "status", type: "info | success | warning | danger", defaultValue: "info", description: "Controls icon and colour treatment." },
77
- { name: "title", type: "string", description: "Required toast heading." },
78
- { name: "description", type: "string", description: "Optional supporting copy." },
79
- { name: "onDismiss", type: "() => void", description: "Shows a close button when provided." },
80
- ]}
81
- />
82
- }
83
- >
84
- <div className="ph-panel">
85
- <div className="mb-4 flex items-center justify-between">
86
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Snack stack demo</h3>
87
- <Button variant="ghost" size="sm" onClick={() => setVisible(toasts.map((t) => t.id))}>
88
- Restore all
89
- </Button>
90
- </div>
91
- <ToastStack className="max-w-xl">
92
- {toasts.map((toast) => {
93
- if (!visible.includes(toast.id)) return null;
94
- return (
95
- <Toast
96
- key={toast.id}
97
- status={toast.status}
98
- title={toast.title}
99
- description={toast.text}
100
- onDismiss={() => setVisible((v) => v.filter((x) => x !== toast.id))}
101
- />
102
- );
103
- })}
104
- </ToastStack>
105
- </div>
106
- </ShowcaseWrapper>
107
- );
108
- }
@@ -1,38 +0,0 @@
1
- import { Button, ShowcaseWrapper, Tooltip, TooltipProvider } from "@/components/ui";
2
-
3
- export default function TooltipShowcase() {
4
- const code = `import { Button, Tooltip, TooltipProvider } from "the-old-ui";
5
-
6
- <TooltipProvider delayDuration={300}>
7
- <div className="ph-panel flex flex-wrap items-center gap-10">
8
- <Tooltip content="Run a HogQL query (Command + /)" side="top">
9
- <Button variant="secondary">Hover me</Button>
10
- </Tooltip>
11
-
12
- <Tooltip content="Available on hover and keyboard focus" side="bottom">
13
- <button type="button" className="ph-tip cursor-help">Dashed chrome</button>
14
- </Tooltip>
15
- </div>
16
- </TooltipProvider>`;
17
-
18
- return (
19
- <ShowcaseWrapper
20
- title="Tooltips"
21
- description="Accessible supporting text on an adaptive inverse surface. Tooltips open on hover or focus, avoid viewport collisions, and dismiss with Escape."
22
- code={code}
23
- filename="TooltipExample.tsx"
24
- >
25
- <TooltipProvider delayDuration={300}>
26
- <div className="ph-panel flex flex-wrap items-center gap-10">
27
- <Tooltip content="Run a HogQL query (Command + /)" side="top">
28
- <Button variant="secondary">Hover me</Button>
29
- </Tooltip>
30
-
31
- <Tooltip content="Available on hover and keyboard focus" side="bottom">
32
- <button type="button" className="ph-tip cursor-help">Dashed chrome</button>
33
- </Tooltip>
34
- </div>
35
- </TooltipProvider>
36
- </ShowcaseWrapper>
37
- );
38
- }
@@ -1,81 +0,0 @@
1
- "use client";
2
-
3
- import { Breadcrumbs, ComponentDocs, Pagination, ShowcaseWrapper } from "@/components/ui";
4
-
5
- const breadcrumbTrail = [
6
- { label: "Project", href: "#" },
7
- { label: "Product analytics", href: "#" },
8
- { label: "Trends", current: true },
9
- ];
10
-
11
- const longBreadcrumbTrail = [
12
- { label: "Organisation", href: "#" },
13
- { label: "Data pipeline", href: "#" },
14
- { label: "Warehouse", href: "#" },
15
- { label: "Sources", href: "#" },
16
- { label: "Stripe sync", current: true },
17
- ];
18
-
19
- export default function UtilityShowcase() {
20
- const code = `import { Breadcrumbs, Pagination } from "the-old-ui";
21
-
22
- <div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
23
- <div className="ph-panel space-y-6">
24
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Breadcrumbs</h3>
25
-
26
- <Breadcrumbs items={breadcrumbTrail} />
27
- <Breadcrumbs items={longBreadcrumbTrail} label="Long breadcrumb" />
28
- </div>
29
-
30
- <div className="ph-panel space-y-6">
31
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Pagination</h3>
32
-
33
- <Pagination page={1} totalPages={12} label="Table pagination" />
34
- <Pagination page={5} totalPages={8} compact label="Compact pagination" />
35
-
36
- <p className="text-xs text-ph-mutedtext">
37
- Pair with table footers. Active page state and disabled arrows are handled by props.
38
- </p>
39
- </div>
40
- </div>`;
41
-
42
- return (
43
- <ShowcaseWrapper
44
- title="Navigation utilities"
45
- description="Breadcrumb and pagination primitives with accessibility and default styling built in."
46
- code={code}
47
- filename="UtilityExample.tsx"
48
- docs={
49
- <ComponentDocs
50
- rows={[
51
- { name: "Breadcrumbs.items", type: "{ label; href?; current? }[]", description: "Trail entries rendered with separators and current page state." },
52
- { name: "Pagination.page", type: "number", description: "Current page." },
53
- { name: "Pagination.totalPages", type: "number", description: "Total page count." },
54
- { name: "Pagination.compact", type: "boolean", defaultValue: "false", description: "Uses a narrower visible page window." },
55
- { name: "Pagination.onPageChange", type: "(page: number) => void", description: "Called by page and arrow buttons." },
56
- ]}
57
- />
58
- }
59
- >
60
- <div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
61
- <div className="ph-panel space-y-6">
62
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Breadcrumbs</h3>
63
-
64
- <Breadcrumbs items={breadcrumbTrail} />
65
- <Breadcrumbs items={longBreadcrumbTrail} label="Long breadcrumb" />
66
- </div>
67
-
68
- <div className="ph-panel space-y-6">
69
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Pagination</h3>
70
-
71
- <Pagination page={1} totalPages={12} label="Table pagination" />
72
- <Pagination page={5} totalPages={8} compact label="Compact pagination" />
73
-
74
- <p className="text-xs text-ph-mutedtext">
75
- Pair with table footers. Active page state and disabled arrows are handled by props.
76
- </p>
77
- </div>
78
- </div>
79
- </ShowcaseWrapper>
80
- );
81
- }