@xenide-io/the-old-ui-theme 0.2.9 → 0.3.1

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 (133) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-5HSOBJ4F.mjs +5968 -0
  3. package/dist/index-BgG8Homu.d.mts +1461 -0
  4. package/dist/index-BgG8Homu.d.ts +1461 -0
  5. package/dist/index.d.mts +206 -100
  6. package/dist/index.d.ts +206 -100
  7. package/dist/index.js +4275 -1455
  8. package/dist/index.mjs +689 -735
  9. package/dist/tailwind-preset.js +7 -0
  10. package/dist/tailwind-preset.mjs +7 -0
  11. package/dist/ui.d.mts +3 -2
  12. package/dist/ui.d.ts +3 -2
  13. package/dist/ui.js +3449 -701
  14. package/dist/ui.mjs +106 -3
  15. package/package.json +20 -16
  16. package/src/app/globals.css +1953 -266
  17. package/src/components/charts/index.ts +9 -8
  18. package/src/components/charts/quill/BarChart.tsx +85 -0
  19. package/src/components/charts/quill/FunnelChart.tsx +49 -0
  20. package/src/components/charts/quill/InsightShell.tsx +27 -0
  21. package/src/components/charts/quill/MetricCard.tsx +44 -0
  22. package/src/components/charts/quill/PieChart.tsx +81 -0
  23. package/src/components/charts/quill/Sparkline.tsx +57 -0
  24. package/src/components/charts/quill/TimeSeriesLineChart.tsx +62 -0
  25. package/src/components/charts/quill/index.ts +9 -0
  26. package/src/components/icons/IconBase.tsx +20 -12
  27. package/src/components/icons/createIconBase.tsx +12 -7
  28. package/src/components/icons/icons.tsx +210 -18
  29. package/src/components/icons/index.ts +3 -0
  30. package/src/components/icons/lemon-brand-icons.tsx +16 -0
  31. package/src/components/icons/lemon-category-icons.tsx +72 -0
  32. package/src/components/icons/lemon-icons.tsx +57 -0
  33. package/src/components/sections/AlertShowcase.tsx +2 -1
  34. package/src/components/sections/BadgeShowcase.tsx +1 -1
  35. package/src/components/sections/ButtonShowcase.tsx +6 -10
  36. package/src/components/sections/CardShowcase.tsx +22 -6
  37. package/src/components/sections/DropdownShowcase.tsx +4 -6
  38. package/src/components/sections/FilterChipsShowcase.tsx +74 -26
  39. package/src/components/sections/FormShowcase.tsx +2 -1
  40. package/src/components/sections/IconShowcase.tsx +195 -212
  41. package/src/components/sections/KbdShowcase.tsx +47 -21
  42. package/src/components/sections/ModalShowcase.tsx +7 -6
  43. package/src/components/sections/NewComponentsShowcase.tsx +1052 -0
  44. package/src/components/sections/ProductLayoutsShowcase.tsx +78 -0
  45. package/src/components/sections/ProgressShowcase.tsx +50 -53
  46. package/src/components/sections/QuillChartShowcase.tsx +92 -0
  47. package/src/components/sections/QuillDashboardShowcase.tsx +149 -0
  48. package/src/components/sections/SidebarShowcase.tsx +151 -0
  49. package/src/components/sections/SwapShowcase.tsx +13 -5
  50. package/src/components/sections/TableShowcase.tsx +2 -0
  51. package/src/components/sections/TooltipShowcase.tsx +19 -25
  52. package/src/components/ui/Alert.tsx +28 -19
  53. package/src/components/ui/AlertDialog.tsx +62 -0
  54. package/src/components/ui/AppLayout.tsx +27 -0
  55. package/src/components/ui/AuthLayout.tsx +58 -0
  56. package/src/components/ui/Autocomplete.tsx +106 -0
  57. package/src/components/ui/Badge.tsx +10 -5
  58. package/src/components/ui/Banner.tsx +63 -0
  59. package/src/components/ui/Button.tsx +22 -12
  60. package/src/components/ui/ButtonChrome.tsx +1 -1
  61. package/src/components/ui/ButtonGroup.tsx +16 -0
  62. package/src/components/ui/Calendar.tsx +6 -7
  63. package/src/components/ui/Card.tsx +21 -11
  64. package/src/components/ui/Chip.tsx +46 -0
  65. package/src/components/ui/Collapsible.tsx +46 -0
  66. package/src/components/ui/CollapsibleSection.tsx +11 -11
  67. package/src/components/ui/Combobox.tsx +119 -0
  68. package/src/components/ui/ContextMenu.tsx +81 -0
  69. package/src/components/ui/DataTable.tsx +133 -0
  70. package/src/components/ui/DatePicker.tsx +96 -0
  71. package/src/components/ui/Dialog.tsx +75 -0
  72. package/src/components/ui/Divider.tsx +39 -0
  73. package/src/components/ui/Dot.tsx +32 -0
  74. package/src/components/ui/DropdownMenu.tsx +189 -65
  75. package/src/components/ui/FilterBar.tsx +165 -0
  76. package/src/components/ui/FilterChips.tsx +65 -35
  77. package/src/components/ui/FilterControls.tsx +30 -0
  78. package/src/components/ui/FormField.tsx +69 -0
  79. package/src/components/ui/Input.tsx +166 -140
  80. package/src/components/ui/InputGroup.tsx +16 -0
  81. package/src/components/ui/Kbd.tsx +88 -13
  82. package/src/components/ui/Lettermark.tsx +47 -0
  83. package/src/components/ui/Link.tsx +32 -0
  84. package/src/components/ui/Loader.tsx +96 -0
  85. package/src/components/ui/LoadingBar.tsx +25 -0
  86. package/src/components/ui/Menubar.tsx +66 -0
  87. package/src/components/ui/Metric.tsx +34 -0
  88. package/src/components/ui/Modal.tsx +66 -36
  89. package/src/components/ui/NumberField.tsx +76 -0
  90. package/src/components/ui/Popover.tsx +73 -0
  91. package/src/components/ui/ProgressCircle.tsx +63 -0
  92. package/src/components/ui/Resizable.tsx +71 -0
  93. package/src/components/ui/Row.tsx +51 -0
  94. package/src/components/ui/ScrollArea.tsx +54 -0
  95. package/src/components/ui/SettingsLayout.tsx +94 -0
  96. package/src/components/ui/ShowcaseWrapper.tsx +4 -16
  97. package/src/components/ui/Sidebar.tsx +77 -0
  98. package/src/components/ui/Snack.tsx +48 -0
  99. package/src/components/ui/Spinner.tsx +30 -0
  100. package/src/components/ui/Splotch.tsx +33 -0
  101. package/src/components/ui/Stepper.tsx +5 -6
  102. package/src/components/ui/Table.tsx +2 -0
  103. package/src/components/ui/Tag.tsx +65 -0
  104. package/src/components/ui/Toggle.tsx +62 -0
  105. package/src/components/ui/Tooltip.test.tsx +58 -0
  106. package/src/components/ui/Tooltip.tsx +211 -0
  107. package/src/components/ui/Widget.tsx +31 -0
  108. package/src/components/ui/first-slice.test.tsx +98 -0
  109. package/src/components/ui/index.ts +335 -22
  110. package/src/components/ui/interaction-primitives.test.tsx +77 -0
  111. package/src/components/ui/kbd-icons.test.tsx +90 -0
  112. package/src/components/ui/product-patterns.test.tsx +77 -0
  113. package/src/styles/themes.css +411 -1
  114. package/tailwind-preset.ts +7 -0
  115. package/dist/chunk-SHF57J7U.mjs +0 -2910
  116. package/dist/index-CmS6hcUk.d.mts +0 -753
  117. package/dist/index-CmS6hcUk.d.ts +0 -753
  118. package/src/components/charts/ph-insight-charts.tsx +0 -162
  119. package/src/components/dashboard/DashboardFiltersBar.tsx +0 -19
  120. package/src/components/dashboard/DashboardGrid.tsx +0 -23
  121. package/src/components/dashboard/DashboardInsightPlaceholder.tsx +0 -37
  122. package/src/components/dashboard/DashboardKpiCard.tsx +0 -25
  123. package/src/components/dashboard/DashboardToolbar.tsx +0 -23
  124. package/src/components/dashboard/DashboardWell.tsx +0 -10
  125. package/src/components/dashboard/InsightMiniCard.tsx +0 -26
  126. package/src/components/dashboard/InsightShell.tsx +0 -37
  127. package/src/components/dashboard/InsightShellHeader.tsx +0 -22
  128. package/src/components/dashboard/MiniTrendBars.tsx +0 -51
  129. package/src/components/dashboard/index.ts +0 -31
  130. package/src/components/dashboard/types.ts +0 -9
  131. package/src/components/sections/ChartShowcase.tsx +0 -190
  132. package/src/components/sections/DashboardShowcase.tsx +0 -191
  133. package/src/components/sections/StatShowcase.tsx +0 -129
@@ -0,0 +1,78 @@
1
+ "use client";
2
+
3
+ import { AuthLayout, AuthCard, SettingsLayout, ShowcaseWrapper, Button } from "@/components/ui";
4
+
5
+ export default function ProductLayoutsShowcase() {
6
+ return (
7
+ <>
8
+ <ShowcaseWrapper
9
+ id="auth"
10
+ title="Auth Layout"
11
+ description="Split-panel authentication shell with brand aside and form column."
12
+ code={`import { AuthLayout, AuthCard } from "@xenide-io/the-old-ui-theme";
13
+
14
+ <AuthLayout>
15
+ <AuthCard title="Sign in" description="Welcome back">
16
+ <input className="ph-input" placeholder="Email" />
17
+ <input className="ph-input" type="password" placeholder="Password" />
18
+ <Button variant="primary">Sign in</Button>
19
+ </AuthCard>
20
+ </AuthLayout>`}
21
+ >
22
+ <div className="max-h-[32rem] overflow-hidden rounded-xl border border-ph-border">
23
+ <AuthLayout>
24
+ <AuthCard title="Sign in" description="Welcome back to your workspace.">
25
+ <div className="space-y-3">
26
+ <input className="ph-input" placeholder="Email" />
27
+ <input className="ph-input" type="password" placeholder="Password" />
28
+ <Button variant="primary" className="w-full">Sign in</Button>
29
+ </div>
30
+ </AuthCard>
31
+ </AuthLayout>
32
+ </div>
33
+ </ShowcaseWrapper>
34
+
35
+ <ShowcaseWrapper
36
+ id="settings"
37
+ title="Settings Layout"
38
+ description="Sidebar navigation and content area for settings pages."
39
+ code={`import { SettingsLayout, SettingsNav } from "@xenide-io/the-old-ui-theme";
40
+
41
+ <SettingsLayout
42
+ title="Settings"
43
+ navigation={<SettingsNav groups={groups} activeId="general" />}
44
+ >
45
+ <p>Settings content</p>
46
+ </SettingsLayout>`}
47
+ >
48
+ <div className="max-h-[28rem] overflow-hidden rounded-xl border border-ph-border">
49
+ <SettingsLayout
50
+ title="Project Settings"
51
+ description="Manage your workspace preferences"
52
+ navigation={
53
+ <div className="ph-settings-nav space-y-5">
54
+ <div>
55
+ <h3 className="mb-1 px-2 text-[10px] font-semibold uppercase tracking-wider text-ph-mutedtext">General</h3>
56
+ <div className="space-y-0.5">
57
+ <a className="ph-settings-nav__item ph-settings-nav__item--active">Overview</a>
58
+ <a className="ph-settings-nav__item">Display</a>
59
+ <a className="ph-settings-nav__item">Notifications</a>
60
+ </div>
61
+ </div>
62
+ <div>
63
+ <h3 className="mb-1 px-2 text-[10px] font-semibold uppercase tracking-wider text-ph-mutedtext">Team</h3>
64
+ <div className="space-y-0.5">
65
+ <a className="ph-settings-nav__item">Members</a>
66
+ <a className="ph-settings-nav__item">Roles</a>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ }
71
+ >
72
+ <p className="text-sm text-ph-subtle">General settings content goes here.</p>
73
+ </SettingsLayout>
74
+ </div>
75
+ </ShowcaseWrapper>
76
+ </>
77
+ );
78
+ }
@@ -1,82 +1,79 @@
1
- import { IconSpinner } from "@/components/icons";
2
- import { ComponentDocs, Progress, ShowcaseWrapper } from "@/components/ui";
1
+ import {
2
+ ComponentDocs,
3
+ Loader,
4
+ LoadingState,
5
+ Progress,
6
+ ShowcaseWrapper,
7
+ Skeleton,
8
+ } from "@/components/ui";
3
9
 
4
10
  export default function ProgressShowcase() {
5
- const code = `import { Progress } from "the-old-ui";
11
+ const code = `import { Loader, LoadingState, Progress, Skeleton } from "@xenide-io/the-old-ui-theme";
6
12
 
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>
13
+ <Progress label="Ingest backlog" value={72} showPercentage />
14
+ <Loader variant="spinner" label="Refreshing insight" />
15
+ <Loader variant="dots" label="Loading events" />
16
+ <Loader variant="pulse" label="Connecting" />
17
+ <LoadingState title="Loading dashboard" description="Restoring the latest results." />
18
+ <div role="status" aria-label="Loading account">
19
+ <Skeleton shape="title" />
20
+ <Skeleton shape="text" />
21
+ <Skeleton shape="short-text" />
28
22
  </div>`;
29
23
 
30
24
  return (
31
25
  <ShowcaseWrapper
32
26
  title="Progress & loading"
33
- description="Linear progress bars, spinners, and skeleton placeholders with semantic colour support."
27
+ description="Determinate progress, compact action loaders, full-region loading states, and structure-matching cold-load skeletons."
34
28
  code={code}
35
- filename="ProgressExample.tsx"
29
+ filename="LoadingExample.tsx"
36
30
  docs={
37
31
  <ComponentDocs
38
32
  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." },
33
+ { name: "Loader.variant", type: "spinner | dots | pulse", defaultValue: "spinner", description: "Indeterminate treatment for compact asynchronous work." },
34
+ { name: "Loader.size", type: "sm | md | lg", defaultValue: "md", description: "Visual loader size." },
35
+ { name: "LoadingState", type: "LoadingStateProps", description: "Centered region state with one accessible status message." },
36
+ { name: "Skeleton.shape", type: "title | text | short-text | avatar | button | block", defaultValue: "text", description: "Decorative skeleton matching expected content geometry." },
37
+ { name: "Progress.value", type: "number", description: "Real determinate progress value." },
45
38
  ]}
46
39
  />
47
40
  }
48
41
  >
49
- <div className="space-y-8">
42
+ <div className="space-y-6">
50
43
  <div className="ph-panel space-y-6">
51
- <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Linear bars</h3>
44
+ <h3 className="text-sm font-semibold uppercase tracking-wider text-ph-mutedtext">Determinate progress</h3>
52
45
  <Progress label="Ingest backlog" value={72} color="bg-ph-brand" showPercentage />
53
46
  <Progress label="Exports" value={45} color="bg-ph-blue" showPercentage />
54
47
  <Progress label="LLM evaluations" value={28} color="bg-ph-purple" showPercentage />
55
48
  </div>
56
49
 
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" />
50
+ <div className="grid gap-4 md:grid-cols-3">
51
+ {(["spinner", "dots", "pulse"] as const).map((variant) => (
52
+ <div key={variant} className="ph-panel flex min-h-28 flex-col items-center justify-center gap-3">
53
+ <Loader variant={variant} size="lg" label={`${variant} loader`} />
54
+ <code className="ph-kbd">{variant}</code>
63
55
  </div>
64
- </div>
56
+ ))}
65
57
  </div>
66
58
 
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
59
+ <div className="grid gap-4 lg:grid-cols-2">
60
+ <div className="ph-panel p-0">
61
+ <LoadingState
62
+ label="Loading dashboard"
63
+ title="Loading dashboard"
64
+ description="Restoring the latest results without pretending progress is measurable."
65
+ />
71
66
  </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 />
67
+ <div className="ph-panel" role="status" aria-label="Loading account summary">
68
+ <div className="mb-5 flex items-center gap-3">
69
+ <Skeleton shape="avatar" />
70
+ <div className="min-w-0 flex-1">
71
+ <Skeleton shape="title" className="mb-2 w-1/2" />
72
+ <Skeleton shape="short-text" className="w-2/3" />
73
+ </div>
74
+ </div>
75
+ <Skeleton shape="block" className="mb-4" />
76
+ <div className="flex justify-end"><Skeleton shape="button" /></div>
80
77
  </div>
81
78
  </div>
82
79
  </div>
@@ -0,0 +1,92 @@
1
+ "use client";
2
+
3
+ import { ShowcaseWrapper } from "@/components/ui";
4
+ import { TimeSeriesLineChart, BarChart, PieChart, Sparkline, MetricCard, FunnelChart, InsightShell } from "@/components/charts/quill";
5
+
6
+ const lineCode = 'import { TimeSeriesLineChart } from "@xenide-io/the-old-ui-theme";\n\n<TimeSeriesLineChart\n labels={["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]}\n series={[\n { key: "views", label: "Pageviews", data: [4200, 5100, 4800, 6200, 5900, 3100, 2800] },\n { key: "signups", label: "Signups", data: [920, 990, 940, 1040, 1012, 540, 510] },\n ]}\n/>';
7
+
8
+ const barCode = 'import { BarChart } from "@xenide-io/the-old-ui-theme";\n\n<BarChart\n labels={["A","B","C","D"]}\n series={[\n { key: "s1", label: "Series 1", data: [30, 45, 25, 60] },\n { key: "s2", label: "Series 2", data: [20, 35, 40, 30] },\n ]}\n/>';
9
+
10
+ const pieCode = 'import { PieChart } from "@xenide-io/the-old-ui-theme";\n\n<PieChart\n slices={[\n { key: "a", label: "Direct", value: 40 },\n { key: "b", label: "Organic", value: 30 },\n { key: "c", label: "Referral", value: 20 },\n { key: "d", label: "Social", value: 10 },\n ]}\n/>';
11
+
12
+ const metricCode = 'import { MetricCard, Sparkline } from "@xenide-io/the-old-ui-theme";\n\n<MetricCard\n value="89.2k"\n label="Page Views"\n change={{ value: 12 }}\n sparklineData={[65, 72, 68, 80, 95, 88, 92]}\n/>';
13
+
14
+ export default function QuillChartShowcase() {
15
+ return (
16
+ <>
17
+ <ShowcaseWrapper
18
+ id="quill-timeline"
19
+ title="Quill TimeSeriesLineChart"
20
+ description="Canvas-based trend line chart with optional grid and crosshair."
21
+ code={lineCode}
22
+ >
23
+ <TimeSeriesLineChart
24
+ labels={["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]}
25
+ series={[
26
+ { key: "views", label: "Pageviews", data: [4200, 5100, 4800, 6200, 5900, 3100, 2800] },
27
+ { key: "signups", label: "Signups", data: [920, 990, 940, 1040, 1012, 540, 510] },
28
+ ]}
29
+ />
30
+ </ShowcaseWrapper>
31
+
32
+ <ShowcaseWrapper
33
+ id="quill-barchart"
34
+ title="Quill BarChart"
35
+ description="Vertical bar chart with multi-series support."
36
+ code={barCode}
37
+ >
38
+ <BarChart
39
+ labels={["A","B","C","D"]}
40
+ series={[
41
+ { key: "s1", label: "Series 1", data: [30, 45, 25, 60] },
42
+ { key: "s2", label: "Series 2", data: [20, 35, 40, 30] },
43
+ ]}
44
+ />
45
+ </ShowcaseWrapper>
46
+
47
+ <ShowcaseWrapper
48
+ id="quill-piechart"
49
+ title="Quill PieChart"
50
+ description="Donut chart with slice labels and legend."
51
+ code={pieCode}
52
+ >
53
+ <PieChart
54
+ slices={[
55
+ { key: "a", label: "Direct", value: 40 },
56
+ { key: "b", label: "Organic", value: 30 },
57
+ { key: "c", label: "Referral", value: 20 },
58
+ { key: "d", label: "Social", value: 10 },
59
+ ]}
60
+ />
61
+ </ShowcaseWrapper>
62
+
63
+ <ShowcaseWrapper
64
+ id="quill-metriccard"
65
+ title="Quill MetricCard and Sparkline"
66
+ description="Metric stat card with sparkline trend."
67
+ code={metricCode}
68
+ >
69
+ <div className="grid gap-4 sm:grid-cols-3">
70
+ <MetricCard
71
+ value="89.2k"
72
+ label="Page Views"
73
+ change={{ value: 12 }}
74
+ sparklineData={[65, 72, 68, 80, 95, 88, 92]}
75
+ />
76
+ <MetricCard
77
+ value="2,847"
78
+ label="Active Users"
79
+ change={{ value: 3 }}
80
+ sparklineData={[42, 48, 45, 52, 50, 48, 55]}
81
+ />
82
+ <MetricCard
83
+ value="23.1%"
84
+ label="Conversion Rate"
85
+ change={{ value: -1.2, positive: false }}
86
+ sparklineData={[24, 23, 23.5, 22.8, 23.2, 22.5, 23.1]}
87
+ />
88
+ </div>
89
+ </ShowcaseWrapper>
90
+ </>
91
+ );
92
+ }
@@ -0,0 +1,149 @@
1
+ "use client";
2
+
3
+ import { ShowcaseWrapper } from "@/components/ui";
4
+ import { InsightShell, MetricCard } from "@/components/charts/quill";
5
+ import { TimeSeriesLineChart, BarChart, PieChart, FunnelChart, Sparkline } from "@/components/charts/quill";
6
+
7
+ export default function QuillDashboardShowcase() {
8
+ return (
9
+ <>
10
+ <ShowcaseWrapper
11
+ id="quill-dashboard"
12
+ title="Quill Dashboard Shells"
13
+ description="InsightShell panels for wrapping Quill charts."
14
+ code={`import { InsightShell } from "@xenide-io/the-old-ui-theme";
15
+ import { TimeSeriesLineChart } from "@xenide-io/the-old-ui-theme";`}
16
+ >
17
+ <div className="grid gap-4 sm:grid-cols-2">
18
+ <InsightShell title="Weekly Active Users" subtitle="Last 14 days" ribbonColor="var(--ph-data-1)">
19
+ <TimeSeriesLineChart
20
+ labels={["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]}
21
+ series={[{ key: "wau", label: "WAU", data: [4200, 5100, 4800, 6200, 5900, 3100, 2800] }]}
22
+ height={180}
23
+ />
24
+ </InsightShell>
25
+ <InsightShell title="Conversion Funnel" subtitle="Step-by-step dropoff" ribbonColor="var(--ph-data-2)">
26
+ <FunnelChart
27
+ steps={[
28
+ { label: "Page Visit", count: 12000 },
29
+ { label: "Sign Up", count: 5400 },
30
+ { label: "Onboarding", count: 3200 },
31
+ { label: "Active Use", count: 1800 },
32
+ ]}
33
+ />
34
+ </InsightShell>
35
+ </div>
36
+ </ShowcaseWrapper>
37
+
38
+ <ShowcaseWrapper
39
+ id="quill-funnel"
40
+ title="Quill Funnel Chart"
41
+ description="Conversion funnel with dropoff percentages."
42
+ code={`import { FunnelChart } from "@xenide-io/the-old-ui-theme";
43
+
44
+ <FunnelChart
45
+ steps={[
46
+ { label: "Visitors", count: 12000 },
47
+ { label: "Signups", count: 5400 },
48
+ { label: "Activated", count: 1800 },
49
+ ]}
50
+ />`}
51
+ >
52
+ <div className="max-w-md">
53
+ <FunnelChart
54
+ steps={[
55
+ { label: "Website Visits", count: 45000 },
56
+ { label: "Product Page", count: 28000 },
57
+ { label: "Added to Cart", count: 12000 },
58
+ { label: "Checkout Started", count: 6500 },
59
+ { label: "Purchase Complete", count: 4200 },
60
+ ]}
61
+ />
62
+ </div>
63
+ </ShowcaseWrapper>
64
+
65
+ <ShowcaseWrapper
66
+ id="quill-metrics-grid"
67
+ title="Quill Metrics Grid"
68
+ description="Metric cards with sparklines for dashboard KPIs."
69
+ code={`import { MetricCard } from "@xenide-io/the-old-ui-theme";`}
70
+ >
71
+ <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
72
+ <MetricCard
73
+ value="$128.4k"
74
+ label="Revenue"
75
+ change={{ value: 12.5 }}
76
+ sparklineData={[80, 95, 88, 102, 110, 108, 128]}
77
+ />
78
+ <MetricCard
79
+ value="4,847"
80
+ label="Active Users"
81
+ change={{ value: 8.3 }}
82
+ sparklineData={[42, 48, 45, 52, 50, 48, 55]}
83
+ />
84
+ <MetricCard
85
+ value="32.1%"
86
+ label="Conversion"
87
+ change={{ value: -2.1, positive: false }}
88
+ sparklineData={[34, 33, 33.5, 32.8, 32.2, 31.5, 32.1]}
89
+ />
90
+ <MetricCard
91
+ value="2.4s"
92
+ label="Avg. Load Time"
93
+ change={{ value: -15, positive: true }}
94
+ sparklineData={[3.2, 2.8, 2.9, 2.6, 2.5, 2.4, 2.4]}
95
+ />
96
+ </div>
97
+ </ShowcaseWrapper>
98
+
99
+ <ShowcaseWrapper
100
+ id="quill-charts-overview"
101
+ title="Quill Charts Overview"
102
+ description="All Quill chart types in one place."
103
+ code={`import { BarChart, PieChart, Sparkline } from "@xenide-io/the-old-ui-theme";`}
104
+ >
105
+ <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
106
+ <InsightShell title="Bar Chart" subtitle="Multi-series bars">
107
+ <BarChart
108
+ labels={["A","B","C","D"]}
109
+ series={[
110
+ { key: "s1", label: "S1", data: [30, 45, 25, 60] },
111
+ { key: "s2", label: "S2", data: [20, 35, 40, 30] },
112
+ ]}
113
+ height={180}
114
+ />
115
+ </InsightShell>
116
+ <InsightShell title="Pie Chart" subtitle="Distribution">
117
+ <div className="flex justify-center">
118
+ <PieChart
119
+ slices={[
120
+ { key: "a", label: "Direct", value: 40 },
121
+ { key: "b", label: "Organic", value: 30 },
122
+ { key: "c", label: "Referral", value: 20 },
123
+ { key: "d", label: "Social", value: 10 },
124
+ ]}
125
+ size={180}
126
+ />
127
+ </div>
128
+ </InsightShell>
129
+ <InsightShell title="Sparklines" subtitle="Inline mini-trends">
130
+ <div className="space-y-4">
131
+ {[
132
+ { label: "Page Views", data: [65, 72, 68, 80, 95, 88, 92], color: "var(--ph-data-1)" },
133
+ { label: "Signups", data: [20, 25, 22, 30, 28, 35, 40], color: "var(--ph-data-2)" },
134
+ { label: "Revenue", data: [80, 95, 88, 102, 110, 108, 128], color: "var(--ph-data-3)" },
135
+ ].map((s) => (
136
+ <div key={s.label} className="flex items-center gap-3">
137
+ <Sparkline data={s.data} color={s.color} width={80} height={24} />
138
+ <div className="min-w-0">
139
+ <p className="text-xs font-medium text-ph-ink">{s.label}</p>
140
+ </div>
141
+ </div>
142
+ ))}
143
+ </div>
144
+ </InsightShell>
145
+ </div>
146
+ </ShowcaseWrapper>
147
+ </>
148
+ );
149
+ }
@@ -0,0 +1,151 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { AppLayout, Sidebar, ShowcaseWrapper, Badge } from "@/components/ui";
5
+ import { Home, Bell, Flag, User, Search, Zap } from "lucide-react";
6
+
7
+ const sampleGroups = [
8
+ {
9
+ label: "Main",
10
+ items: [
11
+ { label: "Home", icon: <Home className="h-4 w-4" />, active: true },
12
+ { label: "Activity", icon: <Bell className="h-4 w-4" />, badge: <Badge variant="danger" size="sm">3</Badge> },
13
+ { label: "Explore", icon: <Search className="h-4 w-4" /> },
14
+ ],
15
+ },
16
+ {
17
+ label: "Workspace",
18
+ items: [
19
+ { label: "Projects", icon: <Flag className="h-4 w-4" /> },
20
+ { label: "People", icon: <User className="h-4 w-4" /> },
21
+ { label: "Automations", icon: <Zap className="h-4 w-4" /> },
22
+ ],
23
+ },
24
+ ];
25
+
26
+ export default function SidebarShowcase() {
27
+ const [collapsed, setCollapsed] = useState(false);
28
+
29
+ return (
30
+ <>
31
+ <ShowcaseWrapper
32
+ id="sidebar-demo"
33
+ title="Sidebar + AppLayout"
34
+ description="Full sidebar and content layout with grouped navigation, icons, badges, and collapse support."
35
+ code={`import { AppLayout, Sidebar } from "@xenide-io/the-old-ui-theme";
36
+
37
+ <AppLayout
38
+ sidebar={
39
+ <Sidebar
40
+ groups={[
41
+ { label: "Main", items: [
42
+ { label: "Home", icon: <Home className="h-4 w-4" />, active: true },
43
+ { label: "Activity", icon: <Bell className="h-4 w-4" />, badge: <Badge>3</Badge> },
44
+ ]},
45
+ ]}
46
+ header={<div className="font-bold">My App</div>}
47
+ footer={<span className="text-xs text-ph-mutedtext">v1.0</span>}
48
+ />
49
+ }
50
+ >
51
+ <div className="p-6">
52
+ <h1>Main content area</h1>
53
+ </div>
54
+ </AppLayout>`}
55
+ >
56
+ <div className="space-y-4">
57
+ <button
58
+ onClick={() => setCollapsed(!collapsed)}
59
+ className="ph-btn ph-btn-secondary ph-btn-sm"
60
+ >
61
+ {collapsed ? "Expand sidebar" : "Collapse sidebar"}
62
+ </button>
63
+ <div className="overflow-hidden rounded-lg border border-ph-border" style={{ height: 360 }}>
64
+ <AppLayout
65
+ sidebarWidth={collapsed ? 56 : 220}
66
+ sidebar={
67
+ <Sidebar
68
+ groups={sampleGroups}
69
+ collapsed={collapsed}
70
+ header={
71
+ <div className="flex items-center gap-2">
72
+ <div className="h-6 w-6 rounded bg-ph-brand flex items-center justify-center text-xs font-bold text-[var(--ph-on-accent)]">T</div>
73
+ {!collapsed && <span className="text-sm font-bold text-ph-ink">The Old UI</span>}
74
+ </div>
75
+ }
76
+ footer={
77
+ !collapsed ? <span className="text-xs text-ph-mutedtext px-2">v0.4.0</span> : null
78
+ }
79
+ />
80
+ }
81
+ >
82
+ <div className="flex h-full items-center justify-center bg-ph-canvas">
83
+ <p className="text-sm text-ph-mutedtext">Content area — click sidebar items</p>
84
+ </div>
85
+ </AppLayout>
86
+ </div>
87
+ </div>
88
+ </ShowcaseWrapper>
89
+
90
+ <ShowcaseWrapper
91
+ id="sidebar-props"
92
+ title="Sidebar Props"
93
+ description="Sidebar component API reference."
94
+ code={`// SidebarGroup
95
+ interface SidebarGroup {
96
+ label: string;
97
+ items: SidebarItemDef[];
98
+ }
99
+
100
+ // SidebarItemDef
101
+ interface SidebarItemDef {
102
+ label: string;
103
+ icon?: ReactNode;
104
+ href?: string;
105
+ badge?: ReactNode;
106
+ active?: boolean;
107
+ onClick?: () => void;
108
+ }
109
+
110
+ // SidebarProps
111
+ interface SidebarProps {
112
+ groups: SidebarGroup[];
113
+ className?: string;
114
+ header?: ReactNode;
115
+ footer?: ReactNode;
116
+ collapsed?: boolean;
117
+ onCollapse?: (collapsed: boolean) => void;
118
+ }
119
+
120
+ // AppLayoutProps
121
+ interface AppLayoutProps {
122
+ sidebar: ReactNode;
123
+ children: ReactNode;
124
+ sidebarWidth?: number;
125
+ className?: string;
126
+ }`}
127
+ >
128
+ <div className="grid gap-4 sm:grid-cols-2">
129
+ <div className="ph-panel space-y-2">
130
+ <h3 className="text-sm font-semibold text-ph-ink">AppLayout</h3>
131
+ <p className="text-xs text-ph-subtle">CSS grid wrapper with fixed sidebar + fluid content.</p>
132
+ <ul className="space-y-1 text-xs text-ph-subtle">
133
+ <li><span className="font-medium text-ph-ink">sidebar</span> — ReactNode for left column</li>
134
+ <li><span className="font-medium text-ph-ink">sidebarWidth</span> — px width (default 240)</li>
135
+ <li><span className="font-medium text-ph-ink">children</span> — main content area</li>
136
+ </ul>
137
+ </div>
138
+ <div className="ph-panel space-y-2">
139
+ <h3 className="text-sm font-semibold text-ph-ink">Sidebar</h3>
140
+ <p className="text-xs text-ph-subtle">Grouped navigation with icons, badges, collapse.</p>
141
+ <ul className="space-y-1 text-xs text-ph-subtle">
142
+ <li><span className="font-medium text-ph-ink">groups</span> — labeled sections with items</li>
143
+ <li><span className="font-medium text-ph-ink">collapsed</span> — icon-only mode</li>
144
+ <li><span className="font-medium text-ph-ink">header/footer</span> — top/bottom slots</li>
145
+ </ul>
146
+ </div>
147
+ </div>
148
+ </ShowcaseWrapper>
149
+ </>
150
+ );
151
+ }