@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,133 @@
1
+ "use client";
2
+
3
+ import { useState, useMemo, type ReactNode } from "react";
4
+ import { cn } from "@/lib/cn";
5
+
6
+ export interface DataTableColumn<T> {
7
+ key: string;
8
+ label: string;
9
+ render?: (item: T) => ReactNode;
10
+ sortable?: boolean;
11
+ className?: string;
12
+ }
13
+
14
+ export interface DataTableProps<T> {
15
+ columns: DataTableColumn<T>[];
16
+ data: T[];
17
+ pageSize?: number;
18
+ searchable?: boolean;
19
+ searchPlaceholder?: string;
20
+ className?: string;
21
+ }
22
+
23
+ export function DataTable<T extends Record<string, any>>({
24
+ columns,
25
+ data,
26
+ pageSize = 10,
27
+ searchable = false,
28
+ searchPlaceholder = "Search...",
29
+ className,
30
+ }: DataTableProps<T>) {
31
+ const [search, setSearch] = useState("");
32
+ const [sortKey, setSortKey] = useState<string | null>(null);
33
+ const [sortDir, setSortDir] = useState<"asc" | "desc">("asc");
34
+ const [page, setPage] = useState(0);
35
+
36
+ const filtered = useMemo(() => {
37
+ let items = data;
38
+ if (search) {
39
+ const q = search.toLowerCase();
40
+ items = items.filter((item) =>
41
+ Object.values(item).some((v) => String(v).toLowerCase().includes(q))
42
+ );
43
+ }
44
+ if (sortKey) {
45
+ items = [...items].sort((a, b) => {
46
+ const av = a[sortKey];
47
+ const bv = b[sortKey];
48
+ const cmp = av < bv ? -1 : av > bv ? 1 : 0;
49
+ return sortDir === "asc" ? cmp : -cmp;
50
+ });
51
+ }
52
+ return items;
53
+ }, [data, search, sortKey, sortDir]);
54
+
55
+ const totalPages = Math.ceil(filtered.length / pageSize);
56
+ const paged = filtered.slice(page * pageSize, (page + 1) * pageSize);
57
+
58
+ const handleSort = (key: string) => {
59
+ if (sortKey === key) {
60
+ setSortDir((d) => (d === "asc" ? "desc" : "asc"));
61
+ } else {
62
+ setSortKey(key);
63
+ setSortDir("asc");
64
+ }
65
+ };
66
+
67
+ return (
68
+ <div className={cn("ph-data-table", className)}>
69
+ {searchable && (
70
+ <div className="ph-data-table__toolbar">
71
+ <input
72
+ type="text"
73
+ value={search}
74
+ onChange={(e) => { setSearch(e.target.value); setPage(0); }}
75
+ placeholder={searchPlaceholder}
76
+ className="ph-input ph-input-sm"
77
+ />
78
+ </div>
79
+ )}
80
+ <div className="ph-table-wrap">
81
+ <table className="ph-table">
82
+ <thead>
83
+ <tr>
84
+ {columns.map((col) => (
85
+ <th
86
+ key={col.key}
87
+ className={cn(col.sortable && "cursor-pointer select-none", col.className)}
88
+ onClick={() => col.sortable && handleSort(col.key)}
89
+ >
90
+ {col.label}
91
+ {sortKey === col.key && (
92
+ <span className="ml-1 inline-block">{sortDir === "asc" ? "\u2191" : "\u2193"}</span>
93
+ )}
94
+ </th>
95
+ ))}
96
+ </tr>
97
+ </thead>
98
+ <tbody>
99
+ {paged.map((item, i) => (
100
+ <tr key={i}>
101
+ {columns.map((col) => (
102
+ <td key={col.key} className={col.className}>
103
+ {col.render ? col.render(item) : item[col.key]}
104
+ </td>
105
+ ))}
106
+ </tr>
107
+ ))}
108
+ {paged.length === 0 && (
109
+ <tr>
110
+ <td colSpan={columns.length} className="text-center text-ph-mutedtext py-8">No results</td>
111
+ </tr>
112
+ )}
113
+ </tbody>
114
+ </table>
115
+ </div>
116
+ {totalPages > 1 && (
117
+ <div className="ph-data-table__pagination">
118
+ <button disabled={page === 0} onClick={() => setPage((p) => p - 1)} className="ph-data-table__page-btn">
119
+ Previous
120
+ </button>
121
+ <span className="text-xs text-ph-mutedtext">
122
+ Page {page + 1} of {totalPages}
123
+ </span>
124
+ <button disabled={page >= totalPages - 1} onClick={() => setPage((p) => p + 1)} className="ph-data-table__page-btn">
125
+ Next
126
+ </button>
127
+ </div>
128
+ )}
129
+ </div>
130
+ );
131
+ }
132
+
133
+ DataTable.displayName = "DataTable";
@@ -0,0 +1,96 @@
1
+ "use client";
2
+
3
+ import { useState, useMemo, type InputHTMLAttributes } from "react";
4
+ import { cn } from "@/lib/cn";
5
+
6
+ const MONTHS = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
7
+ const DAYS = ["Su","Mo","Tu","We","Th","Fr","Sa"];
8
+
9
+ export interface DatePickerProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "type"> {
10
+ value?: Date;
11
+ onChange?: (date: Date) => void;
12
+ }
13
+
14
+ export function DatePicker({ value, onChange, className, ...props }: DatePickerProps) {
15
+ const [open, setOpen] = useState(false);
16
+ const [viewDate, setViewDate] = useState(value ?? new Date());
17
+ const selected = value;
18
+
19
+ const days = useMemo(() => {
20
+ const year = viewDate.getFullYear();
21
+ const month = viewDate.getMonth();
22
+ const first = new Date(year, month, 1).getDay();
23
+ const last = new Date(year, month + 1, 0).getDate();
24
+ const prevLast = new Date(year, month, 0).getDate();
25
+ const cells: { day: number; month: "prev" | "current" | "next" }[] = [];
26
+ for (let i = first - 1; i >= 0; i--) cells.push({ day: prevLast - i, month: "prev" });
27
+ for (let d = 1; d <= last; d++) cells.push({ day: d, month: "current" });
28
+ const remaining = 42 - cells.length;
29
+ for (let d = 1; d <= remaining; d++) cells.push({ day: d, month: "next" });
30
+ return cells;
31
+ }, [viewDate]);
32
+
33
+ const isSelected = (d: number, m: "prev" | "current" | "next") => {
34
+ if (!selected || m !== "current") return false;
35
+ const date = new Date(viewDate.getFullYear(), viewDate.getMonth(), d);
36
+ return date.toDateString() === selected.toDateString();
37
+ };
38
+
39
+ const selectDay = (d: number, m: string) => {
40
+ const month = m === "prev" ? viewDate.getMonth() - 1 : m === "next" ? viewDate.getMonth() + 1 : viewDate.getMonth();
41
+ const year = month < 0 ? viewDate.getFullYear() - 1 : month > 11 ? viewDate.getFullYear() + 1 : viewDate.getFullYear();
42
+ const adjustedMonth = ((month % 12) + 12) % 12;
43
+ const date = new Date(year, adjustedMonth, d);
44
+ onChange?.(date);
45
+ setOpen(false);
46
+ };
47
+
48
+ const nav = (delta: number) => setViewDate(new Date(viewDate.getFullYear(), viewDate.getMonth() + delta, 1));
49
+
50
+ return (
51
+ <div className={cn("ph-datepicker relative", className)}>
52
+ <input
53
+ type="text"
54
+ readOnly
55
+ value={selected ? `${MONTHS[selected.getMonth()]} ${selected.getDate()}, ${selected.getFullYear()}` : ""}
56
+ onFocus={() => setOpen(true)}
57
+ placeholder="Pick a date"
58
+ className="ph-input w-full cursor-pointer"
59
+ {...props}
60
+ />
61
+ {open && (
62
+ <div className="ph-datepicker__dropdown">
63
+ <div className="ph-datepicker__nav">
64
+ <button type="button" onClick={() => nav(-1)} className="ph-datepicker__nav-btn" aria-label="Previous month">
65
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M7 3L4 6l3 3"/></svg>
66
+ </button>
67
+ <span className="ph-datepicker__nav-label">{MONTHS[viewDate.getMonth()]} {viewDate.getFullYear()}</span>
68
+ <button type="button" onClick={() => nav(1)} className="ph-datepicker__nav-btn" aria-label="Next month">
69
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M5 3l3 3-3 3"/></svg>
70
+ </button>
71
+ </div>
72
+ <div className="ph-datepicker__grid">
73
+ {DAYS.map((d) => <div key={d} className="ph-datepicker__day-header">{d}</div>)}
74
+ {days.map((d, i) => (
75
+ <button
76
+ key={i}
77
+ type="button"
78
+ disabled={d.month !== "current"}
79
+ onClick={() => selectDay(d.day, d.month)}
80
+ className={cn(
81
+ "ph-datepicker__day",
82
+ d.month !== "current" && "ph-datepicker__day--other",
83
+ isSelected(d.day, d.month) && "ph-datepicker__day--selected"
84
+ )}
85
+ >
86
+ {d.day}
87
+ </button>
88
+ ))}
89
+ </div>
90
+ </div>
91
+ )}
92
+ </div>
93
+ );
94
+ }
95
+
96
+ DatePicker.displayName = "DatePicker";
@@ -0,0 +1,75 @@
1
+ import { useState, type ReactNode } from "react";
2
+ import { Modal, type ModalProps } from "@/components/ui/Modal";
3
+ import { Button, type ButtonProps } from "@/components/ui/Button";
4
+
5
+ export interface DialogProps extends Omit<ModalProps, "onClose"> {
6
+ isOpen?: boolean;
7
+ onClose?: () => void;
8
+ onConfirm?: () => void | Promise<void>;
9
+ confirmText?: string;
10
+ cancelText?: string;
11
+ confirmProps?: Partial<ButtonProps>;
12
+ cancelProps?: Partial<ButtonProps>;
13
+ children?: ReactNode;
14
+ }
15
+
16
+ export function Dialog({
17
+ isOpen: openProp,
18
+ onClose,
19
+ onConfirm,
20
+ confirmText = "Confirm",
21
+ cancelText = "Cancel",
22
+ confirmProps,
23
+ cancelProps,
24
+ children,
25
+ title,
26
+ ...modalProps
27
+ }: DialogProps) {
28
+ const [loading, setLoading] = useState(false);
29
+ const isOpen = openProp ?? true;
30
+
31
+ const handleConfirm = async () => {
32
+ if (!onConfirm) return;
33
+ setLoading(true);
34
+ try {
35
+ await onConfirm();
36
+ } finally {
37
+ setLoading(false);
38
+ }
39
+ onClose?.();
40
+ };
41
+
42
+ return (
43
+ <Modal
44
+ open={isOpen}
45
+ onClose={onClose}
46
+ title={title}
47
+ footer={
48
+ <div className="flex justify-end gap-2">
49
+ <Button variant="secondary" {...cancelProps} onClick={onClose}>
50
+ {cancelText}
51
+ </Button>
52
+ {onConfirm && (
53
+ <Button
54
+ variant="primary"
55
+ loading={loading}
56
+ {...confirmProps}
57
+ onClick={handleConfirm}
58
+ >
59
+ {confirmText}
60
+ </Button>
61
+ )}
62
+ </div>
63
+ }
64
+ {...modalProps}
65
+ >
66
+ {children}
67
+ </Modal>
68
+ );
69
+ }
70
+
71
+ Dialog.displayName = "Dialog";
72
+
73
+ export function confirmDialog(props: DialogProps) {
74
+ return <Dialog {...props} />;
75
+ }
@@ -0,0 +1,39 @@
1
+ import type { HTMLAttributes } from "react";
2
+ import { cn } from "@/lib/cn";
3
+
4
+ export interface DividerProps extends HTMLAttributes<HTMLDivElement> {
5
+ vertical?: boolean;
6
+ dashed?: boolean;
7
+ thick?: boolean;
8
+ label?: string;
9
+ }
10
+
11
+ export function Divider({
12
+ vertical = false,
13
+ dashed = false,
14
+ thick = false,
15
+ label,
16
+ className,
17
+ ...props
18
+ }: DividerProps) {
19
+ return (
20
+ <div
21
+ role="separator"
22
+ aria-orientation={vertical ? "vertical" : "horizontal"}
23
+ className={cn(
24
+ "ph-divider",
25
+ vertical && "ph-divider--vertical",
26
+ thick && "ph-divider--thick",
27
+ dashed && "ph-divider--dashed",
28
+ !!label && "ph-divider--with-label",
29
+ !className && (vertical ? "mx-2 self-stretch" : "my-2"),
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ {label && <span className="ph-divider__label">{label}</span>}
35
+ </div>
36
+ );
37
+ }
38
+
39
+ Divider.displayName = "Divider";
@@ -0,0 +1,32 @@
1
+ import type { HTMLAttributes } from "react";
2
+ import { cn } from "@/lib/cn";
3
+
4
+ export interface DotProps extends HTMLAttributes<HTMLSpanElement> {
5
+ color?: "green" | "yellow" | "red" | "blue" | "gray";
6
+ size?: "sm" | "md";
7
+ }
8
+
9
+ const colorMap = {
10
+ green: "bg-ph-success",
11
+ yellow: "bg-ph-warning",
12
+ red: "bg-ph-danger",
13
+ blue: "bg-ph-info",
14
+ gray: "bg-ph-mutedtext",
15
+ };
16
+
17
+ export function Dot({ color = "gray", size = "md", className, ...props }: DotProps) {
18
+ return (
19
+ <span
20
+ className={cn(
21
+ "ph-dot inline-block shrink-0 rounded-full",
22
+ size === "sm" ? "h-1.5 w-1.5" : "h-2.5 w-2.5",
23
+ colorMap[color],
24
+ className
25
+ )}
26
+ aria-hidden="true"
27
+ {...props}
28
+ />
29
+ );
30
+ }
31
+
32
+ Dot.displayName = "Dot";