@etherealui/react 0.0.0-stage → 0.0.3

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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -2
  3. package/dist/index.d.mts +583 -0
  4. package/dist/index.d.ts +583 -0
  5. package/dist/index.js +5189 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +5189 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +83 -3
  10. package/src/blocks/app-shell.tsx +441 -0
  11. package/src/blocks/billing-card.tsx +2 -0
  12. package/src/blocks/data-table.tsx +479 -0
  13. package/src/blocks/filter-bar.tsx +134 -0
  14. package/src/blocks/header-navbar.tsx +7 -0
  15. package/src/blocks/metric-grid.tsx +5 -0
  16. package/src/blocks/profile-form.tsx +2 -0
  17. package/src/blocks/security-settings.tsx +2 -0
  18. package/src/blocks/settings-blocks.tsx +406 -0
  19. package/src/blocks/sidebar.tsx +6 -0
  20. package/src/blocks/stat-card.tsx +7 -0
  21. package/src/blocks/stat-cards.tsx +212 -0
  22. package/src/blocks/team-members.tsx +5 -0
  23. package/src/index.ts +114 -0
  24. package/src/primitives/accordion.tsx +61 -0
  25. package/src/primitives/announcement.tsx +33 -0
  26. package/src/primitives/avatar.tsx +156 -0
  27. package/src/primitives/badge.tsx +108 -0
  28. package/src/primitives/breadcrumb.tsx +45 -0
  29. package/src/primitives/button-group.tsx +79 -0
  30. package/src/primitives/button.tsx +165 -0
  31. package/src/primitives/carousel.tsx +84 -0
  32. package/src/primitives/chart.tsx +831 -0
  33. package/src/primitives/checkbox.tsx +26 -0
  34. package/src/primitives/chip.tsx +37 -0
  35. package/src/primitives/close-button.tsx +29 -0
  36. package/src/primitives/color-picker.tsx +62 -0
  37. package/src/primitives/combobox.tsx +123 -0
  38. package/src/primitives/command-palette.tsx +216 -0
  39. package/src/primitives/context-menu.tsx +84 -0
  40. package/src/primitives/date-calendar.tsx +76 -0
  41. package/src/primitives/date-picker.tsx +400 -0
  42. package/src/primitives/dialog.tsx +279 -0
  43. package/src/primitives/divider.tsx +31 -0
  44. package/src/primitives/drawer.tsx +95 -0
  45. package/src/primitives/dropdown-menu.tsx +164 -0
  46. package/src/primitives/file-upload.tsx +123 -0
  47. package/src/primitives/icon-button.tsx +23 -0
  48. package/src/primitives/input.tsx +124 -0
  49. package/src/primitives/modal.tsx +26 -0
  50. package/src/primitives/pagination.tsx +58 -0
  51. package/src/primitives/popover.tsx +28 -0
  52. package/src/primitives/progress.tsx +145 -0
  53. package/src/primitives/radio-group.tsx +63 -0
  54. package/src/primitives/select.tsx +207 -0
  55. package/src/primitives/skeleton.tsx +61 -0
  56. package/src/primitives/slider.tsx +44 -0
  57. package/src/primitives/switch.tsx +146 -0
  58. package/src/primitives/table.tsx +47 -0
  59. package/src/primitives/tabs.tsx +86 -0
  60. package/src/primitives/textarea.tsx +40 -0
  61. package/src/primitives/toast.tsx +71 -0
  62. package/src/primitives/tooltip.tsx +58 -0
  63. package/src/styles/globals.css +49 -0
  64. package/src/templates/control-tower.tsx +41 -0
  65. package/src/templates/executive-analytics.tsx +272 -0
  66. package/src/templates/workspace-settings.tsx +179 -0
  67. package/src/utils/cn.ts +7 -0
@@ -0,0 +1,165 @@
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+ import { Loader2, X } from "lucide-react"
5
+ import { cn } from "../utils/cn"
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/30 disabled:pointer-events-none disabled:opacity-50 cursor-pointer select-none",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default:
13
+ "bg-zinc-900 text-white hover:bg-zinc-800 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-200 shadow-2xs",
14
+ primary:
15
+ "bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 shadow-2xs",
16
+ glow:
17
+ "bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 shadow-2xs",
18
+ secondary:
19
+ "bg-zinc-100 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700",
20
+ outline:
21
+ "border border-zinc-200 bg-white text-zinc-700 hover:bg-zinc-50 hover:text-zinc-900 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100 dark:hover:bg-zinc-800",
22
+ ghost:
23
+ "text-zinc-600 hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100",
24
+ destructive:
25
+ "bg-rose-600 text-white hover:bg-rose-700 dark:bg-rose-600 dark:hover:bg-rose-500",
26
+ },
27
+ size: {
28
+ default: "h-9 px-3.5 py-2 text-xs",
29
+ sm: "h-8 rounded-md px-2.5 text-xs",
30
+ lg: "h-10 rounded-lg px-5 text-sm",
31
+ icon: "h-8 w-8",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: "default",
36
+ size: "default",
37
+ },
38
+ }
39
+ )
40
+
41
+ export interface ButtonProps
42
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
43
+ VariantProps<typeof buttonVariants> {
44
+ asChild?: boolean
45
+ loading?: boolean
46
+ }
47
+
48
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
49
+ ({ className, variant, size, asChild = false, loading = false, children, disabled, ...props }, ref) => {
50
+ const Comp = asChild ? Slot : "button"
51
+ return (
52
+ <Comp
53
+ className={cn(buttonVariants({ variant, size, className }))}
54
+ ref={ref}
55
+ disabled={disabled || loading}
56
+ {...props}
57
+ >
58
+ {loading && <Loader2 className="h-3.5 w-3.5 animate-spin shrink-0" />}
59
+ {children}
60
+ </Comp>
61
+ )
62
+ }
63
+ )
64
+ Button.displayName = "Button"
65
+
66
+ export interface CloseButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
67
+ size?: "sm" | "default"
68
+ }
69
+
70
+ const CloseButton = React.forwardRef<HTMLButtonElement, CloseButtonProps>(
71
+ ({ className, size = "default", ...props }, ref) => (
72
+ <button
73
+ ref={ref}
74
+ type="button"
75
+ aria-label="Close"
76
+ className={cn(
77
+ "inline-flex items-center justify-center rounded-lg text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800 dark:hover:text-zinc-200 cursor-pointer",
78
+ size === "sm" ? "h-6 w-6" : "h-8 w-8",
79
+ className
80
+ )}
81
+ {...props}
82
+ >
83
+ <X className={size === "sm" ? "h-3.5 w-3.5" : "h-4 w-4"} />
84
+ </button>
85
+ )
86
+ )
87
+ CloseButton.displayName = "CloseButton"
88
+
89
+ export interface ButtonGroupProps extends React.HTMLAttributes<HTMLDivElement> {
90
+ attached?: boolean
91
+ }
92
+
93
+ const ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(
94
+ ({ className, attached = true, ...props }, ref) => (
95
+ <div
96
+ ref={ref}
97
+ role="group"
98
+ className={cn(
99
+ "inline-flex items-center",
100
+ attached
101
+ ? "rounded-lg border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900 p-0.5 [&>button]:border-0 [&>button]:rounded-md [&>button]:shadow-none"
102
+ : "gap-2",
103
+ className
104
+ )}
105
+ {...props}
106
+ />
107
+ )
108
+ )
109
+ ButtonGroup.displayName = "ButtonGroup"
110
+
111
+ export interface ToggleGroupItem {
112
+ value: string
113
+ label: React.ReactNode
114
+ icon?: React.ReactNode
115
+ }
116
+
117
+ export interface ToggleGroupProps {
118
+ items: ToggleGroupItem[]
119
+ value: string
120
+ onValueChange: (value: string) => void
121
+ size?: "sm" | "default"
122
+ className?: string
123
+ }
124
+
125
+ const ToggleGroup: React.FC<ToggleGroupProps> = ({
126
+ items,
127
+ value,
128
+ onValueChange,
129
+ size = "default",
130
+ className,
131
+ }) => {
132
+ return (
133
+ <div
134
+ role="group"
135
+ className={cn(
136
+ "inline-flex items-center rounded-lg border border-zinc-200 bg-zinc-100/80 dark:border-zinc-800 dark:bg-zinc-900 p-0.5 gap-0.5",
137
+ className
138
+ )}
139
+ >
140
+ {items.map((item) => {
141
+ const active = item.value === value
142
+ return (
143
+ <button
144
+ key={item.value}
145
+ type="button"
146
+ onClick={() => onValueChange(item.value)}
147
+ className={cn(
148
+ "inline-flex items-center gap-1.5 rounded-md font-medium transition-all cursor-pointer",
149
+ size === "sm" ? "px-2.5 py-1 text-xs" : "px-3 py-1.5 text-xs",
150
+ active
151
+ ? "bg-white text-zinc-900 shadow-2xs dark:bg-zinc-800 dark:text-zinc-100"
152
+ : "text-zinc-500 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-200"
153
+ )}
154
+ >
155
+ {item.icon}
156
+ {item.label}
157
+ </button>
158
+ )
159
+ })}
160
+ </div>
161
+ )
162
+ }
163
+ ToggleGroup.displayName = "ToggleGroup"
164
+
165
+ export { Button, CloseButton, ButtonGroup, ToggleGroup, buttonVariants }
@@ -0,0 +1,84 @@
1
+ import * as React from "react"
2
+ import { ChevronLeft, ChevronRight } from "lucide-react"
3
+ import { cn } from "../utils/cn"
4
+
5
+ export interface CarouselSlide {
6
+ title: string
7
+ subtitle: string
8
+ metric: string
9
+ }
10
+
11
+ export interface CarouselProps {
12
+ slides?: CarouselSlide[]
13
+ className?: string
14
+ }
15
+
16
+ export const Carousel: React.FC<CarouselProps> = ({
17
+ slides = [
18
+ {
19
+ title: "Q4 Revenue Velocity",
20
+ subtitle: "Net dollar retention across enterprise accounts",
21
+ metric: "128.4%",
22
+ },
23
+ {
24
+ title: "Global Checkout Conversion",
25
+ subtitle: "30-day rolling average across 14 currencies",
26
+ metric: "4.82%",
27
+ },
28
+ {
29
+ title: "Customer Support SLA",
30
+ subtitle: "Median first response time for priority tickets",
31
+ metric: "3m 12s",
32
+ },
33
+ ],
34
+ className,
35
+ }) => {
36
+ const [idx, setIdx] = React.useState(0)
37
+ const current = slides[idx]
38
+
39
+ return (
40
+ <div
41
+ className={cn(
42
+ "w-full max-w-md rounded-2xl border border-zinc-200 bg-white p-5 dark:border-zinc-800 dark:bg-zinc-900",
43
+ className
44
+ )}
45
+ >
46
+ <div className="flex items-center justify-between">
47
+ <span className="text-[11px] font-medium text-zinc-400">
48
+ Slide {idx + 1} of {slides.length}
49
+ </span>
50
+ <div className="flex items-center gap-1">
51
+ <button
52
+ type="button"
53
+ onClick={() =>
54
+ setIdx((p) => (p - 1 + slides.length) % slides.length)
55
+ }
56
+ className="rounded-lg border border-zinc-200 p-1 text-zinc-500 hover:bg-zinc-50 dark:border-zinc-800 dark:hover:bg-zinc-800 cursor-pointer"
57
+ >
58
+ <ChevronLeft className="h-3.5 w-3.5" />
59
+ </button>
60
+ <button
61
+ type="button"
62
+ onClick={() => setIdx((p) => (p + 1) % slides.length)}
63
+ className="rounded-lg border border-zinc-200 p-1 text-zinc-500 hover:bg-zinc-50 dark:border-zinc-800 dark:hover:bg-zinc-800 cursor-pointer"
64
+ >
65
+ <ChevronRight className="h-3.5 w-3.5" />
66
+ </button>
67
+ </div>
68
+ </div>
69
+ <div className="mt-4 space-y-1">
70
+ <div className="text-2xl font-semibold text-zinc-900 dark:text-zinc-100">
71
+ {current.metric}
72
+ </div>
73
+ <div className="text-xs font-medium text-zinc-800 dark:text-zinc-200">
74
+ {current.title}
75
+ </div>
76
+ <p className="text-xs text-zinc-500 dark:text-zinc-400">
77
+ {current.subtitle}
78
+ </p>
79
+ </div>
80
+ </div>
81
+ )
82
+ }
83
+ Carousel.displayName = "Carousel"
84
+