@hilum/ui 0.1.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/dist/icons.d.ts +1 -0
  4. package/dist/icons.js +3 -0
  5. package/dist/icons.js.map +1 -0
  6. package/dist/index.d.ts +992 -0
  7. package/dist/index.js +4433 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/tokens.css +265 -0
  10. package/dist/tokens.d.ts +189 -0
  11. package/dist/tokens.js +193 -0
  12. package/dist/tokens.js.map +1 -0
  13. package/package.json +80 -0
  14. package/src/components/__tests__/data.test.tsx +180 -0
  15. package/src/components/__tests__/disclosure.test.tsx +198 -0
  16. package/src/components/__tests__/display.test.tsx +262 -0
  17. package/src/components/__tests__/feedback.test.tsx +138 -0
  18. package/src/components/__tests__/form.test.tsx +297 -0
  19. package/src/components/__tests__/layout.test.tsx +388 -0
  20. package/src/components/__tests__/overlay.test.tsx +90 -0
  21. package/src/components/__tests__/primitives.test.tsx +248 -0
  22. package/src/components/accordion.tsx +68 -0
  23. package/src/components/action-panel.tsx +112 -0
  24. package/src/components/activity-feed.tsx +69 -0
  25. package/src/components/alert-dialog.tsx +132 -0
  26. package/src/components/alert.tsx +44 -0
  27. package/src/components/aspect-ratio.tsx +19 -0
  28. package/src/components/avatar-stack.tsx +70 -0
  29. package/src/components/avatar.tsx +103 -0
  30. package/src/components/badge.tsx +33 -0
  31. package/src/components/breadcrumb.tsx +76 -0
  32. package/src/components/button-group.tsx +45 -0
  33. package/src/components/button.tsx +60 -0
  34. package/src/components/calendar.tsx +61 -0
  35. package/src/components/card-heading.tsx +60 -0
  36. package/src/components/card.tsx +120 -0
  37. package/src/components/carousel.tsx +222 -0
  38. package/src/components/chart.tsx +77 -0
  39. package/src/components/checkbox.tsx +35 -0
  40. package/src/components/collapsible.tsx +9 -0
  41. package/src/components/color-input.tsx +90 -0
  42. package/src/components/color-picker.tsx +111 -0
  43. package/src/components/combobox.tsx +207 -0
  44. package/src/components/command-palette.tsx +137 -0
  45. package/src/components/command.tsx +248 -0
  46. package/src/components/context-menu.tsx +201 -0
  47. package/src/components/data-table.tsx +151 -0
  48. package/src/components/date-picker.tsx +56 -0
  49. package/src/components/description-list.tsx +70 -0
  50. package/src/components/dialog.tsx +97 -0
  51. package/src/components/drawer.tsx +90 -0
  52. package/src/components/dropdown-menu.tsx +202 -0
  53. package/src/components/empty-state.tsx +43 -0
  54. package/src/components/field.tsx +45 -0
  55. package/src/components/grid-list.tsx +159 -0
  56. package/src/components/hover-card.tsx +34 -0
  57. package/src/components/input-group.tsx +134 -0
  58. package/src/components/input-number.tsx +142 -0
  59. package/src/components/input-otp.tsx +68 -0
  60. package/src/components/input.tsx +23 -0
  61. package/src/components/kbd.tsx +18 -0
  62. package/src/components/label.tsx +23 -0
  63. package/src/components/media-object.tsx +49 -0
  64. package/src/components/menubar.tsx +235 -0
  65. package/src/components/native-select.tsx +44 -0
  66. package/src/components/navigation-menu.tsx +158 -0
  67. package/src/components/notification.tsx +109 -0
  68. package/src/components/page-heading.tsx +125 -0
  69. package/src/components/pagination.tsx +89 -0
  70. package/src/components/popover.tsx +35 -0
  71. package/src/components/progress.tsx +23 -0
  72. package/src/components/property-row.tsx +56 -0
  73. package/src/components/radio-card.tsx +105 -0
  74. package/src/components/radio-group.tsx +38 -0
  75. package/src/components/resizable.tsx +74 -0
  76. package/src/components/scroll-area.tsx +42 -0
  77. package/src/components/section-heading.tsx +64 -0
  78. package/src/components/select.tsx +130 -0
  79. package/src/components/separator.tsx +25 -0
  80. package/src/components/sheet.tsx +117 -0
  81. package/src/components/sidebar.tsx +636 -0
  82. package/src/components/skeleton.tsx +14 -0
  83. package/src/components/slider.tsx +24 -0
  84. package/src/components/sonner.tsx +34 -0
  85. package/src/components/spinner.tsx +37 -0
  86. package/src/components/stacked-list.tsx +64 -0
  87. package/src/components/stat-card.tsx +54 -0
  88. package/src/components/steps.tsx +179 -0
  89. package/src/components/switch.tsx +33 -0
  90. package/src/components/table.tsx +101 -0
  91. package/src/components/tabs.tsx +55 -0
  92. package/src/components/textarea.tsx +21 -0
  93. package/src/components/toggle-group.tsx +49 -0
  94. package/src/components/toggle.tsx +66 -0
  95. package/src/components/tooltip.tsx +43 -0
  96. package/src/icons.ts +158 -0
  97. package/src/index.ts +84 -0
  98. package/src/lib/utils.ts +6 -0
  99. package/src/tokens/tokens.ts +194 -0
@@ -0,0 +1,43 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Tooltip } from "radix-ui";
5
+ import { cn } from "../lib/utils";
6
+
7
+ function TooltipProvider({
8
+ children,
9
+ ...props
10
+ }: React.ComponentPropsWithoutRef<typeof Tooltip.Provider>) {
11
+ return (
12
+ <Tooltip.Provider delayDuration={300} {...props}>
13
+ {children}
14
+ </Tooltip.Provider>
15
+ );
16
+ }
17
+
18
+ const TooltipRoot = Tooltip.Root;
19
+ const TooltipTrigger = Tooltip.Trigger;
20
+
21
+ const TooltipContent = React.forwardRef<
22
+ React.ComponentRef<typeof Tooltip.Content>,
23
+ React.ComponentPropsWithoutRef<typeof Tooltip.Content>
24
+ >(({ className, sideOffset = 4, ...props }, ref) => (
25
+ <Tooltip.Portal>
26
+ <Tooltip.Content
27
+ ref={ref}
28
+ sideOffset={sideOffset}
29
+ className={cn(
30
+ "z-50 rounded-lg bg-taupe-900 px-2.5 py-1.5 caption text-white",
31
+ "animate-in fade-in-0 zoom-in-95",
32
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
33
+ "data-[side=bottom]:slide-in-from-top-1 data-[side=top]:slide-in-from-bottom-1",
34
+ "data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1",
35
+ className,
36
+ )}
37
+ {...props}
38
+ />
39
+ </Tooltip.Portal>
40
+ ));
41
+ TooltipContent.displayName = "TooltipContent";
42
+
43
+ export { TooltipProvider, TooltipRoot as Tooltip, TooltipTrigger, TooltipContent };
package/src/icons.ts ADDED
@@ -0,0 +1,158 @@
1
+ // @hilum/ui/icons — curated re-exports from lucide-react.
2
+ //
3
+ // Apps import as `import { ChevronDown, Plus } from "@hilum/ui/icons"` — they
4
+ // never depend on lucide-react directly. This stops drift between Hilum apps
5
+ // using slightly different icon sets (D10).
6
+ //
7
+ // To add an icon: add the named re-export below. Tree-shaking ensures
8
+ // consumers only ship what they import.
9
+
10
+ export {
11
+ // System / nav
12
+ Menu,
13
+ X,
14
+ ChevronDown,
15
+ ChevronUp,
16
+ ChevronLeft,
17
+ ChevronRight,
18
+ ChevronsUpDown,
19
+ ChevronsLeft,
20
+ ChevronsRight,
21
+ ArrowLeft,
22
+ ArrowRight,
23
+ ArrowUp,
24
+ ArrowDown,
25
+ ArrowUpRight,
26
+ ArrowDownRight,
27
+ MoreHorizontal,
28
+ MoreVertical,
29
+ // Status
30
+ Check,
31
+ AlertCircle,
32
+ AlertTriangle,
33
+ Info,
34
+ CircleHelp,
35
+ CheckCircle2,
36
+ XCircle,
37
+ CircleAlert,
38
+ CircleCheck,
39
+ CircleX,
40
+ Loader,
41
+ Loader2,
42
+ // Action
43
+ Plus,
44
+ Minus,
45
+ Trash,
46
+ Trash2,
47
+ Edit,
48
+ Edit2,
49
+ Edit3,
50
+ Pencil,
51
+ Save,
52
+ Copy,
53
+ Search,
54
+ Filter,
55
+ Settings,
56
+ Settings2,
57
+ RotateCcw,
58
+ RotateCw,
59
+ Download,
60
+ Upload,
61
+ Share,
62
+ Share2,
63
+ ExternalLink,
64
+ // Visibility
65
+ Eye,
66
+ EyeOff,
67
+ Lock,
68
+ Unlock,
69
+ Pin,
70
+ PinOff,
71
+ // Toggles
72
+ Sun,
73
+ Moon,
74
+ MonitorSmartphone,
75
+ // Common nouns
76
+ Home,
77
+ User,
78
+ Users,
79
+ Bell,
80
+ Mail,
81
+ Phone,
82
+ Calendar,
83
+ Clock,
84
+ File,
85
+ FileText,
86
+ Folder,
87
+ FolderOpen,
88
+ Image,
89
+ Video,
90
+ Music,
91
+ Heart,
92
+ Star,
93
+ Bookmark,
94
+ Tag,
95
+ // Layout / design
96
+ Layers,
97
+ Layout,
98
+ LayoutDashboard,
99
+ LayoutGrid,
100
+ LayoutList,
101
+ AlignLeft,
102
+ AlignCenter,
103
+ AlignRight,
104
+ AlignJustify,
105
+ Bold,
106
+ Italic,
107
+ Underline,
108
+ Strikethrough,
109
+ Type,
110
+ Image as ImageIcon,
111
+ Square,
112
+ Circle,
113
+ Triangle,
114
+ // Auth
115
+ LogIn,
116
+ LogOut,
117
+ KeyRound,
118
+ ShieldCheck,
119
+ // Money / commerce
120
+ CreditCard,
121
+ ShoppingCart,
122
+ ShoppingBag,
123
+ Wallet,
124
+ DollarSign,
125
+ // Brand context
126
+ Atom,
127
+ Blocks,
128
+ Megaphone,
129
+ Palette,
130
+ ShoppingBag as ShopBag,
131
+ // Misc
132
+ Sparkles,
133
+ Zap,
134
+ Rocket,
135
+ Flame,
136
+ Lightbulb,
137
+ Wand2,
138
+ Hand,
139
+ MousePointer,
140
+ MousePointer2,
141
+ Move,
142
+ Maximize2,
143
+ Minimize2,
144
+ RefreshCw,
145
+ RefreshCcw,
146
+ Send,
147
+ Paperclip,
148
+ Link,
149
+ Link2,
150
+ Globe,
151
+ Compass,
152
+ Map,
153
+ MapPin,
154
+ Navigation,
155
+ Check as CheckIcon,
156
+ } from "lucide-react";
157
+
158
+ export type { LucideIcon, LucideProps } from "lucide-react";
package/src/index.ts ADDED
@@ -0,0 +1,84 @@
1
+ // @hilum/ui — Hilum design system primitives.
2
+ // All components, utilities, and re-exports.
3
+ //
4
+ // Hilum apps are plain React (Vite / Electron / React Native via future
5
+ // @hilum/ui-native). No Next.js, no "use client" directives — D11.
6
+
7
+ // Utilities
8
+ export { cn } from "./lib/utils";
9
+
10
+ // Components (alphabetical)
11
+ export * from "./components/accordion";
12
+ export * from "./components/action-panel";
13
+ export * from "./components/activity-feed";
14
+ export * from "./components/alert-dialog";
15
+ export * from "./components/alert";
16
+ export * from "./components/aspect-ratio";
17
+ export * from "./components/avatar-stack";
18
+ export * from "./components/avatar";
19
+ export * from "./components/badge";
20
+ export * from "./components/breadcrumb";
21
+ export * from "./components/button-group";
22
+ export * from "./components/button";
23
+ export * from "./components/calendar";
24
+ export * from "./components/card-heading";
25
+ export * from "./components/card";
26
+ export * from "./components/carousel";
27
+ export * from "./components/chart";
28
+ export * from "./components/checkbox";
29
+ export * from "./components/collapsible";
30
+ export * from "./components/color-input";
31
+ export * from "./components/color-picker";
32
+ export * from "./components/combobox";
33
+ export * from "./components/command-palette";
34
+ export * from "./components/command";
35
+ export * from "./components/context-menu";
36
+ export * from "./components/data-table";
37
+ export * from "./components/date-picker";
38
+ export * from "./components/description-list";
39
+ export * from "./components/dialog";
40
+ export * from "./components/drawer";
41
+ export * from "./components/dropdown-menu";
42
+ export * from "./components/empty-state";
43
+ export * from "./components/field";
44
+ export * from "./components/grid-list";
45
+ export * from "./components/hover-card";
46
+ export * from "./components/input-group";
47
+ export * from "./components/input-number";
48
+ export * from "./components/input-otp";
49
+ export * from "./components/input";
50
+ export * from "./components/kbd";
51
+ export * from "./components/label";
52
+ export * from "./components/media-object";
53
+ export * from "./components/menubar";
54
+ export * from "./components/native-select";
55
+ export * from "./components/navigation-menu";
56
+ export * from "./components/notification";
57
+ export * from "./components/page-heading";
58
+ export * from "./components/pagination";
59
+ export * from "./components/popover";
60
+ export * from "./components/progress";
61
+ export * from "./components/property-row";
62
+ export * from "./components/radio-card";
63
+ export * from "./components/radio-group";
64
+ export * from "./components/resizable";
65
+ export * from "./components/scroll-area";
66
+ export * from "./components/section-heading";
67
+ export * from "./components/select";
68
+ export * from "./components/separator";
69
+ export * from "./components/sheet";
70
+ export * from "./components/sidebar";
71
+ export * from "./components/skeleton";
72
+ export * from "./components/slider";
73
+ export * from "./components/sonner";
74
+ export * from "./components/spinner";
75
+ export * from "./components/stacked-list";
76
+ export * from "./components/stat-card";
77
+ export * from "./components/steps";
78
+ export * from "./components/switch";
79
+ export * from "./components/table";
80
+ export * from "./components/tabs";
81
+ export * from "./components/textarea";
82
+ export * from "./components/toggle-group";
83
+ export * from "./components/toggle";
84
+ export * from "./components/tooltip";
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,194 @@
1
+ // @hilum/ui/tokens — JS-first design tokens (D6).
2
+ //
3
+ // This module is the single source of truth for the Hilum visual identity.
4
+ // A build step (scripts/build-tokens.mjs) reads the compiled output of this
5
+ // file and emits dist/tokens.css for consumers to `@import`.
6
+ //
7
+ // Brand model: D8 — fully fixed. No per-app overrides.
8
+ // Color modes: D7 — light + dark, both auto (`prefers-color-scheme`) and
9
+ // explicit via `[data-theme]`.
10
+ //
11
+ // Core brand colors:
12
+ // brand.primary #C100F1 — vivid purple — purple-500 on the scale below
13
+ // brand.secondary #FFF5BF — pale lemon — butter-200 on the scale below
14
+ //
15
+ // taupe — neutral spine for text, borders, and structure (unchanged)
16
+
17
+ export const tokens = {
18
+ /* ============================================================== *
19
+ * PALETTE — concrete colors *
20
+ * ============================================================== */
21
+
22
+ taupe: {
23
+ 50: "#f9f7f5",
24
+ 100: "#f2eeea",
25
+ 200: "#e3dcd4",
26
+ 300: "#c9beb3",
27
+ 400: "#a8978a",
28
+ 500: "#7d6960",
29
+ 600: "#5d4e47",
30
+ 700: "#4a3d38",
31
+ 800: "#332924",
32
+ 900: "#26181a",
33
+ 950: "#160e0a",
34
+ },
35
+
36
+ // Pale lemon — anchor: butter-200 = #FFF5BF
37
+ butter: {
38
+ 50: "#ffffe8",
39
+ 100: "#fffad0",
40
+ 200: "#fff5bf",
41
+ 300: "#fde870",
42
+ 400: "#f6d42a",
43
+ 500: "#dab010",
44
+ 600: "#a88008",
45
+ 700: "#7c5c04",
46
+ 800: "#543e02",
47
+ 900: "#382801",
48
+ 950: "#221600",
49
+ },
50
+
51
+ // Vivid purple — anchor: purple-500 = #C100F1 (brand.primary)
52
+ purple: {
53
+ 50: "#fdf0ff",
54
+ 100: "#f5d6ff",
55
+ 200: "#e8a8ff",
56
+ 300: "#d870f9",
57
+ 400: "#c840f6",
58
+ 500: "#c100f1",
59
+ 600: "#9c00c0",
60
+ 700: "#740092",
61
+ 800: "#4e0062",
62
+ 900: "#330040",
63
+ 950: "#200028",
64
+ },
65
+
66
+ // Legacy functional colors — used by components not yet migrated to the new palette.
67
+ brand: {
68
+ primary: "#C100F1", // purple-500
69
+ secondary: "#FFF5BF", // butter-200
70
+ },
71
+
72
+ destructive: "#dc2626", // red-600
73
+
74
+ /* ============================================================== *
75
+ * SEMANTIC — what components reference *
76
+ * ============================================================== */
77
+
78
+ semantic: {
79
+ light: {
80
+ background: "#ffffff",
81
+ foreground: "#26181a", // taupe-900
82
+ card: "#ffffff",
83
+ cardForeground: "#26181a",
84
+ surface: "#f9f7f5", // taupe-50
85
+ surfaceForeground: "#332924", // taupe-800
86
+ border: "#f2eeea", // taupe-100
87
+ input: "#f2eeea",
88
+ muted: "#f9f7f5",
89
+ mutedForeground: "#7d6960", // taupe-500
90
+ accent: "#fdf0ff", // purple-50
91
+ accentForeground: "#740092", // purple-700
92
+ primary: "#c100f1", // purple-500 = brand.primary
93
+ primaryForeground: "#ffffff",
94
+ secondary: "#f9f7f5", // taupe-50
95
+ secondaryForeground: "#4a3d38", // taupe-700
96
+ destructive: "#dc2626",
97
+ destructiveForeground: "#ffffff",
98
+ success: "#CDEA19", // lime — functional semantic only
99
+ successForeground: "#26181a",
100
+ warning: "#fff5bf", // butter-200 = brand.secondary
101
+ warningForeground: "#26181a", // taupe-900
102
+ ring: "#c100f1", // purple-500 = brand.primary
103
+ },
104
+ dark: {
105
+ background: "#160e0a", // taupe-950
106
+ foreground: "#f9f7f5", // taupe-50
107
+ card: "#26181a", // taupe-900
108
+ cardForeground: "#f9f7f5",
109
+ surface: "#26181a",
110
+ surfaceForeground: "#f2eeea",
111
+ border: "#332924", // taupe-800
112
+ input: "#332924",
113
+ muted: "#26181a",
114
+ mutedForeground: "#a8978a", // taupe-400
115
+ accent: "#330040", // purple-900
116
+ accentForeground: "#f5d6ff", // purple-100
117
+ primary: "#c100f1", // purple-500 — brand stays consistent (D8)
118
+ primaryForeground: "#ffffff",
119
+ secondary: "#26181a",
120
+ secondaryForeground: "#f2eeea",
121
+ destructive: "#ef4444", // red-500 (slightly lighter for dark)
122
+ destructiveForeground: "#ffffff",
123
+ success: "#CDEA19", // lime — functional semantic only
124
+ successForeground: "#160e0a",
125
+ warning: "#221600", // butter-950 surface
126
+ warningForeground: "#fffad0", // butter-100
127
+ ring: "#c100f1", // purple-500 = brand.primary
128
+ },
129
+ },
130
+
131
+ /* ============================================================== *
132
+ * TYPOGRAPHY *
133
+ * ============================================================== */
134
+
135
+ fontFamily: {
136
+ sans: 'Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
137
+ serif: '"Instrument Serif", ui-serif, Georgia, serif',
138
+ mono: 'ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace',
139
+ },
140
+
141
+ /** Type scale utilities — emitted as Tailwind v4 `@utility` blocks. */
142
+ typeScale: {
143
+ "display-xl": { family: "serif", size: "3rem", weight: 400, lineHeight: "1.15" },
144
+ display: { family: "serif", size: "2.25rem", weight: 400, lineHeight: "1.15" },
145
+ "heading-xl": { family: "serif", size: "1.875rem", weight: 400, lineHeight: "1.2" },
146
+ heading: { family: "serif", size: "1.5rem", weight: 400, lineHeight: "1.2" },
147
+ subheading: { family: "serif", size: "1.25rem", weight: 400, lineHeight: "1.4" },
148
+ "body-lg": { family: "sans", size: "1rem", weight: 400, lineHeight: "1.625" },
149
+ body: { family: "sans", size: "0.875rem", weight: 400, lineHeight: "1.625" },
150
+ caption: { family: "sans", size: "0.75rem", weight: 400, lineHeight: "1.625" },
151
+ "caption-xs": { family: "sans", size: "0.625rem", weight: 400, lineHeight: "1.625" },
152
+ label: {
153
+ family: "sans",
154
+ size: "0.75rem",
155
+ weight: 600,
156
+ lineHeight: "1",
157
+ letterSpacing: "0.1em",
158
+ textTransform: "uppercase" as const,
159
+ },
160
+ },
161
+
162
+ /* ============================================================== *
163
+ * GEOMETRY *
164
+ * ============================================================== */
165
+
166
+ radius: {
167
+ base: "0.5rem",
168
+ sm: "calc(0.5rem - 4px)",
169
+ md: "calc(0.5rem - 2px)",
170
+ lg: "0.5rem",
171
+ xl: "calc(0.5rem + 4px)",
172
+ full: "9999px",
173
+ },
174
+
175
+ shadow: {
176
+ natural:
177
+ "0 0px 0px 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06)",
178
+ elevated:
179
+ "0 0px 0px 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06), 0 12px 12px -6px rgba(0, 0, 0, 0.04), 0 24px 24px -12px rgba(0, 0, 0, 0.04), 0 24px 24px 2px rgba(0, 0, 0, 0.1)",
180
+ },
181
+
182
+ /* ============================================================== *
183
+ * ANIMATION *
184
+ * ============================================================== */
185
+
186
+ animation: {
187
+ "accordion-down": "accordion-down 0.2s ease-out",
188
+ "accordion-up": "accordion-up 0.2s ease-out",
189
+ "caret-blink": "caret-blink 1.25s ease-out infinite",
190
+ },
191
+ } as const;
192
+
193
+ export type Tokens = typeof tokens;
194
+ export type SemanticTokens = typeof tokens.semantic.light;