@moontra/moonui 2.1.9 → 2.2.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.
- package/dist/index.d.mts +1656 -0
- package/dist/index.d.ts +1656 -0
- package/dist/index.js +1847 -469
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1679 -471
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/components/ui/accordion.tsx +1 -1
- package/src/components/ui/alert.tsx +123 -93
- package/src/components/ui/aspect-ratio.tsx +1 -1
- package/src/components/ui/avatar.tsx +8 -6
- package/src/components/ui/badge.tsx +20 -18
- package/src/components/ui/breadcrumb.tsx +12 -10
- package/src/components/ui/button.stories.tsx +4 -2
- package/src/components/ui/button.tsx +71 -68
- package/src/components/ui/calendar.tsx +2 -2
- package/src/components/ui/card-input.tsx +231 -0
- package/src/components/ui/card.stories.tsx +2 -0
- package/src/components/ui/card.tsx +9 -7
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/collapsible.tsx +3 -3
- package/src/components/ui/color-picker.tsx +2 -2
- package/src/components/ui/command.tsx +4 -4
- package/src/components/ui/data-table.stories.tsx +4 -2
- package/src/components/ui/data-table.tsx +8 -8
- package/src/components/ui/date-picker.stories.tsx +2 -0
- package/src/components/ui/date-picker.tsx +25 -15
- package/src/components/ui/dialog.tsx +2 -2
- package/src/components/ui/draggable-list.tsx +3 -1
- package/src/components/ui/dropdown-menu.tsx +2 -2
- package/src/components/ui/file-upload.tsx +2 -2
- package/src/components/ui/github-stars.tsx +1 -1
- package/src/components/ui/index.ts +357 -45
- package/src/components/ui/input.stories.tsx +2 -0
- package/src/components/ui/input.tsx +3 -1
- package/src/components/ui/locked-component.tsx +222 -0
- package/src/components/ui/moon-logo.tsx +1 -1
- package/src/components/ui/pagination.tsx +10 -8
- package/src/components/ui/phone-input.tsx +172 -0
- package/src/components/ui/popover-pro.tsx +424 -0
- package/src/components/ui/popover.tsx +3 -3
- package/src/components/ui/progress.tsx +1 -1
- package/src/components/ui/radio-group.tsx +1 -1
- package/src/components/ui/rich-text-editor/index.tsx +2 -1
- package/src/components/ui/scroll-area.tsx +48 -0
- package/src/components/ui/select.tsx +7 -3
- package/src/components/ui/separator.tsx +2 -2
- package/src/components/ui/skeleton.tsx +19 -7
- package/src/components/ui/slider.tsx +1 -1
- package/src/components/ui/swipeable-card.tsx +2 -0
- package/src/components/ui/switch.tsx +1 -1
- package/src/components/ui/table.tsx +7 -5
- package/src/components/ui/tabs.tsx +6 -1
- package/src/components/ui/tags-input.tsx +130 -0
- package/src/components/ui/textarea.tsx +3 -1
- package/src/components/ui/toast.tsx +5 -3
- package/src/components/ui/toggle.tsx +2 -3
- package/src/components/ui/tooltip.tsx +2 -5
- package/src/index.tsx +4 -46
- package/src/lib/micro-interactions.ts +2 -1
- package/src/lib/performance-profiler.ts +79 -0
- package/src/styles/index.css +315 -2
- package/src/use-performance-optimizer.ts +26 -26
- package/src/use-scroll-animation.ts +5 -7
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import * as React from "react";
|
|
2
4
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
5
|
import { cn } from "../../lib/utils";
|
|
@@ -13,89 +15,88 @@ const buttonVariants = cva(
|
|
|
13
15
|
["inline-flex items-center justify-center gap-2 whitespace-nowrap",
|
|
14
16
|
"font-medium relative",
|
|
15
17
|
"transition-all duration-200 ease-out",
|
|
16
|
-
"
|
|
18
|
+
"transform active:scale-[0.98]",
|
|
17
19
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
18
|
-
"disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none"],
|
|
20
|
+
"disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none disabled:transform-none"],
|
|
19
21
|
{
|
|
20
22
|
variants: {
|
|
21
23
|
variant: {
|
|
22
24
|
primary: [
|
|
23
25
|
"bg-primary text-primary-foreground",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
26
|
+
"dark:bg-primary dark:text-primary-foreground",
|
|
27
|
+
"hover:bg-primary/90 dark:hover:bg-primary/90",
|
|
28
|
+
"active:bg-primary/80 dark:active:bg-primary/80",
|
|
29
|
+
"shadow-sm hover:shadow-md",
|
|
30
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
29
31
|
"transition-all duration-200",
|
|
30
32
|
],
|
|
31
33
|
secondary: [
|
|
32
|
-
"bg-
|
|
33
|
-
"hover:bg-gray-200 dark:hover:bg-gray-700/90",
|
|
34
|
-
"active:bg-gray-300 dark:active:bg-gray-600/90",
|
|
35
|
-
"border border-transparent dark:border-gray-700",
|
|
36
|
-
"focus-visible:ring-gray-400/30 dark:focus-visible:ring-gray-500/40",
|
|
34
|
+
"bg-gray-100 text-gray-900",
|
|
37
35
|
"dark:bg-gray-800 dark:text-gray-100",
|
|
38
|
-
"
|
|
36
|
+
"hover:bg-gray-200 dark:hover:bg-gray-700",
|
|
37
|
+
"active:bg-gray-300 dark:active:bg-gray-600",
|
|
38
|
+
"border border-gray-200 dark:border-gray-700",
|
|
39
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
40
|
+
"shadow-sm hover:shadow-md",
|
|
39
41
|
],
|
|
40
42
|
outline: [
|
|
41
43
|
"bg-background text-foreground",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"hover:bg-
|
|
45
|
-
"active:bg-
|
|
46
|
-
"focus-visible:ring-
|
|
47
|
-
"
|
|
48
|
-
"dark:shadow-sm dark:shadow-gray-950/10",
|
|
44
|
+
"dark:bg-background dark:text-foreground",
|
|
45
|
+
"border border-input dark:border-input",
|
|
46
|
+
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent dark:hover:text-accent-foreground",
|
|
47
|
+
"active:bg-accent/80 dark:active:bg-accent/80",
|
|
48
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
49
|
+
"transition-all duration-200",
|
|
49
50
|
],
|
|
50
51
|
ghost: [
|
|
51
|
-
"text-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"transition-
|
|
52
|
+
"text-gray-700",
|
|
53
|
+
"dark:text-gray-300",
|
|
54
|
+
"hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-gray-800 dark:hover:text-gray-100",
|
|
55
|
+
"active:bg-gray-200 dark:active:bg-gray-700",
|
|
56
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
57
|
+
"transition-all duration-200",
|
|
57
58
|
],
|
|
58
59
|
destructive: [
|
|
59
|
-
"bg-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"transition-
|
|
60
|
+
"bg-destructive text-destructive-foreground",
|
|
61
|
+
"dark:bg-destructive dark:text-destructive-foreground",
|
|
62
|
+
"hover:bg-destructive/90 dark:hover:bg-destructive/90",
|
|
63
|
+
"active:bg-destructive/80 dark:active:bg-destructive/80",
|
|
64
|
+
"shadow-sm hover:shadow-md",
|
|
65
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
66
|
+
"transition-all duration-200",
|
|
66
67
|
],
|
|
67
68
|
success: [
|
|
68
|
-
"bg-success text-
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"transition-
|
|
69
|
+
"bg-success text-success-foreground",
|
|
70
|
+
"dark:bg-success dark:text-success-foreground",
|
|
71
|
+
"hover:bg-success/90 dark:hover:bg-success/90",
|
|
72
|
+
"active:bg-success/80 dark:active:bg-success/80",
|
|
73
|
+
"shadow-sm hover:shadow-md",
|
|
74
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
75
|
+
"transition-all duration-200",
|
|
75
76
|
],
|
|
76
77
|
link: [
|
|
77
78
|
"text-primary bg-transparent",
|
|
78
79
|
"underline-offset-4 hover:underline",
|
|
79
|
-
"hover:text-primary
|
|
80
|
+
"hover:text-primary/80 active:text-primary/70",
|
|
80
81
|
"p-0 h-auto",
|
|
81
|
-
"dark:text-blue-400 dark:hover:text-blue-300",
|
|
82
|
-
"dark:active:text-blue-500",
|
|
83
82
|
"transition-colors duration-200",
|
|
84
83
|
],
|
|
85
84
|
gradient: [
|
|
86
|
-
"bg-gradient-to-r from-
|
|
87
|
-
"hover:from-
|
|
88
|
-
"active:from-
|
|
89
|
-
"shadow-
|
|
85
|
+
"bg-gradient-to-r from-purple-500 to-pink-500 text-white",
|
|
86
|
+
"hover:from-purple-600 hover:to-pink-600",
|
|
87
|
+
"active:from-purple-700 active:to-pink-700",
|
|
88
|
+
"shadow-xl shadow-purple-500/40",
|
|
89
|
+
"hover:shadow-2xl hover:shadow-purple-500/50",
|
|
90
90
|
"focus-visible:ring-purple-500/50",
|
|
91
91
|
"transition-all duration-300",
|
|
92
92
|
],
|
|
93
93
|
glow: [
|
|
94
|
-
"bg-
|
|
95
|
-
"shadow-
|
|
96
|
-
"hover:shadow-
|
|
97
|
-
"active:shadow-
|
|
98
|
-
"
|
|
94
|
+
"bg-blue-500 text-white",
|
|
95
|
+
"shadow-[0_0_30px_rgba(59,130,246,0.5)]",
|
|
96
|
+
"hover:shadow-[0_0_40px_rgba(59,130,246,0.7)]",
|
|
97
|
+
"active:shadow-[0_0_20px_rgba(59,130,246,0.4)]",
|
|
98
|
+
"hover:bg-blue-600",
|
|
99
|
+
"focus-visible:ring-blue-500/50",
|
|
99
100
|
"transition-all duration-300",
|
|
100
101
|
],
|
|
101
102
|
soft: [
|
|
@@ -119,29 +120,31 @@ const buttonVariants = cva(
|
|
|
119
120
|
"transition-all duration-200",
|
|
120
121
|
],
|
|
121
122
|
neon: [
|
|
122
|
-
"bg-transparent text-
|
|
123
|
-
"border-2 border-
|
|
124
|
-
"hover:bg-
|
|
125
|
-
"hover:shadow-[
|
|
126
|
-
"active:shadow-[
|
|
127
|
-
"focus-visible:ring-
|
|
123
|
+
"bg-transparent text-green-400",
|
|
124
|
+
"border-2 border-green-400",
|
|
125
|
+
"hover:bg-green-400 hover:text-gray-900",
|
|
126
|
+
"hover:shadow-[0_0_30px_rgba(74,222,128,0.6)]",
|
|
127
|
+
"active:shadow-[0_0_15px_rgba(74,222,128,0.4)]",
|
|
128
|
+
"focus-visible:ring-green-400/50",
|
|
128
129
|
"transition-all duration-300",
|
|
129
130
|
],
|
|
130
131
|
},
|
|
131
132
|
size: {
|
|
132
|
-
xs: "h-7 px-2.5 text-xs
|
|
133
|
-
sm: "h-8 px-3 text-sm
|
|
134
|
-
md: "h-10 px-4 text-base
|
|
135
|
-
lg: "h-12 px-6 text-lg
|
|
136
|
-
xl: "h-14 px-8 text-xl
|
|
137
|
-
icon: "h-10 w-10 p-2
|
|
138
|
-
"icon-sm": "h-8 w-8 p-1.5
|
|
139
|
-
"icon-lg": "h-12 w-12 p-3
|
|
133
|
+
xs: "h-7 px-2.5 text-xs",
|
|
134
|
+
sm: "h-8 px-3 text-sm",
|
|
135
|
+
md: "h-10 px-4 text-base",
|
|
136
|
+
lg: "h-12 px-6 text-lg",
|
|
137
|
+
xl: "h-14 px-8 text-xl",
|
|
138
|
+
icon: "h-10 w-10 p-2",
|
|
139
|
+
"icon-sm": "h-8 w-8 p-1.5",
|
|
140
|
+
"icon-lg": "h-12 w-12 p-3",
|
|
140
141
|
},
|
|
141
142
|
rounded: {
|
|
142
|
-
default: "",
|
|
143
|
+
default: "rounded-xl",
|
|
143
144
|
full: "rounded-full",
|
|
144
145
|
none: "rounded-none",
|
|
146
|
+
sm: "rounded-lg",
|
|
147
|
+
lg: "rounded-2xl",
|
|
145
148
|
},
|
|
146
149
|
fullWidth: {
|
|
147
150
|
true: "w-full",
|
|
@@ -199,7 +202,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
199
202
|
|
|
200
203
|
return (
|
|
201
204
|
<Comp
|
|
202
|
-
className={cn(buttonVariants({ variant, size, rounded, fullWidth, className }))}
|
|
205
|
+
className={cn("moonui-theme", buttonVariants({ variant, size, rounded, fullWidth, className }))}
|
|
203
206
|
ref={ref}
|
|
204
207
|
disabled={disabled || loading}
|
|
205
208
|
data-loading={loading ? "" : undefined}
|
|
@@ -164,9 +164,9 @@ function Calendar({
|
|
|
164
164
|
const days = getDaysInMonth();
|
|
165
165
|
|
|
166
166
|
return (
|
|
167
|
-
<div className={cn("p-0", className)}>
|
|
167
|
+
<div className={cn("moonui-theme", "p-0", className)}>
|
|
168
168
|
{/* Header */}
|
|
169
|
-
<div className="flex items-center justify-between px-6 py-4">
|
|
169
|
+
<div className="flex items-center justify-between px-6 py-4 border-b border-border/50 dark:border-gray-700/50">
|
|
170
170
|
<button
|
|
171
171
|
onClick={handlePreviousMonth}
|
|
172
172
|
className={cn(
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "../../lib/utils"
|
|
5
|
+
import { Input } from "@/components/ui"
|
|
6
|
+
import { CreditCard } from "lucide-react"
|
|
7
|
+
|
|
8
|
+
// Card type detection
|
|
9
|
+
const getCardType = (number: string): string => {
|
|
10
|
+
const patterns = {
|
|
11
|
+
visa: /^4/,
|
|
12
|
+
mastercard: /^5[1-5]/,
|
|
13
|
+
amex: /^3[47]/,
|
|
14
|
+
discover: /^6(?:011|5)/,
|
|
15
|
+
diners: /^3(?:0[0-5]|[68])/,
|
|
16
|
+
jcb: /^35/,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
for (const [type, pattern] of Object.entries(patterns)) {
|
|
20
|
+
if (pattern.test(number)) return type
|
|
21
|
+
}
|
|
22
|
+
return "unknown"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Format card number with spaces
|
|
26
|
+
const formatCardNumber = (value: string, cardType: string): string => {
|
|
27
|
+
const cleaned = value.replace(/\s+/g, "")
|
|
28
|
+
const groups = cardType === "amex" ? [4, 6, 5] : [4, 4, 4, 4]
|
|
29
|
+
|
|
30
|
+
let formatted = ""
|
|
31
|
+
let position = 0
|
|
32
|
+
|
|
33
|
+
for (const group of groups) {
|
|
34
|
+
if (position >= cleaned.length) break
|
|
35
|
+
if (formatted) formatted += " "
|
|
36
|
+
formatted += cleaned.slice(position, position + group)
|
|
37
|
+
position += group
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return formatted
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Card Number Input
|
|
44
|
+
export interface CardNumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value"> {
|
|
45
|
+
value?: string
|
|
46
|
+
onChange?: (value: string, cardType: string) => void
|
|
47
|
+
showIcon?: boolean
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const CardNumberInput = React.forwardRef<HTMLInputElement, CardNumberInputProps>(
|
|
51
|
+
({ className, value = "", onChange, showIcon = true, size, ...props }, ref) => {
|
|
52
|
+
const [cardType, setCardType] = React.useState("unknown")
|
|
53
|
+
|
|
54
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
55
|
+
const rawValue = e.target.value.replace(/\D/g, "")
|
|
56
|
+
const detectedType = getCardType(rawValue)
|
|
57
|
+
setCardType(detectedType)
|
|
58
|
+
|
|
59
|
+
const maxLength = detectedType === "amex" ? 15 : 16
|
|
60
|
+
const truncated = rawValue.slice(0, maxLength)
|
|
61
|
+
const formatted = formatCardNumber(truncated, detectedType)
|
|
62
|
+
|
|
63
|
+
onChange?.(truncated, detectedType)
|
|
64
|
+
|
|
65
|
+
// Update the input value
|
|
66
|
+
e.target.value = formatted
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<div className="relative">
|
|
71
|
+
<Input
|
|
72
|
+
ref={ref}
|
|
73
|
+
type="text"
|
|
74
|
+
inputMode="numeric"
|
|
75
|
+
autoComplete="cc-number"
|
|
76
|
+
placeholder="1234 5678 9012 3456"
|
|
77
|
+
value={formatCardNumber(value, cardType)}
|
|
78
|
+
onChange={handleChange}
|
|
79
|
+
className={cn(showIcon && "pl-10", className)}
|
|
80
|
+
{...props}
|
|
81
|
+
/>
|
|
82
|
+
{showIcon && (
|
|
83
|
+
<CreditCard className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
CardNumberInput.displayName = "CardNumberInput"
|
|
90
|
+
|
|
91
|
+
// Card Expiry Input
|
|
92
|
+
export interface CardExpiryInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value"> {
|
|
93
|
+
value?: string
|
|
94
|
+
onChange?: (value: string) => void
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const CardExpiryInput = React.forwardRef<HTMLInputElement, CardExpiryInputProps>(
|
|
98
|
+
({ className, value = "", onChange, size, ...props }, ref) => {
|
|
99
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
100
|
+
let rawValue = e.target.value.replace(/\D/g, "")
|
|
101
|
+
|
|
102
|
+
if (rawValue.length >= 2) {
|
|
103
|
+
const month = parseInt(rawValue.slice(0, 2))
|
|
104
|
+
if (month > 12) {
|
|
105
|
+
rawValue = "12" + rawValue.slice(2)
|
|
106
|
+
} else if (month === 0) {
|
|
107
|
+
rawValue = "01" + rawValue.slice(2)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
rawValue = rawValue.slice(0, 4)
|
|
112
|
+
let formatted = rawValue
|
|
113
|
+
|
|
114
|
+
if (rawValue.length >= 2) {
|
|
115
|
+
formatted = rawValue.slice(0, 2) + "/" + rawValue.slice(2)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
onChange?.(rawValue)
|
|
119
|
+
e.target.value = formatted
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const formattedValue = value.length >= 2 ? value.slice(0, 2) + "/" + value.slice(2) : value
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<Input
|
|
126
|
+
ref={ref}
|
|
127
|
+
type="text"
|
|
128
|
+
inputMode="numeric"
|
|
129
|
+
autoComplete="cc-exp"
|
|
130
|
+
placeholder="MM/YY"
|
|
131
|
+
value={formattedValue}
|
|
132
|
+
onChange={handleChange}
|
|
133
|
+
className={className}
|
|
134
|
+
{...props}
|
|
135
|
+
/>
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
CardExpiryInput.displayName = "CardExpiryInput"
|
|
140
|
+
|
|
141
|
+
// Card CVC Input
|
|
142
|
+
export interface CardCVCInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value"> {
|
|
143
|
+
value?: string
|
|
144
|
+
onChange?: (value: string) => void
|
|
145
|
+
cardType?: string
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export const CardCVCInput = React.forwardRef<HTMLInputElement, CardCVCInputProps>(
|
|
149
|
+
({ className, value = "", onChange, cardType = "unknown", size, ...props }, ref) => {
|
|
150
|
+
const maxLength = cardType === "amex" ? 4 : 3
|
|
151
|
+
|
|
152
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
153
|
+
const rawValue = e.target.value.replace(/\D/g, "").slice(0, maxLength)
|
|
154
|
+
onChange?.(rawValue)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<Input
|
|
159
|
+
ref={ref}
|
|
160
|
+
type="text"
|
|
161
|
+
inputMode="numeric"
|
|
162
|
+
autoComplete="cc-csc"
|
|
163
|
+
placeholder={cardType === "amex" ? "1234" : "123"}
|
|
164
|
+
value={value}
|
|
165
|
+
onChange={handleChange}
|
|
166
|
+
maxLength={maxLength}
|
|
167
|
+
className={className}
|
|
168
|
+
{...props}
|
|
169
|
+
/>
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
CardCVCInput.displayName = "CardCVCInput"
|
|
174
|
+
|
|
175
|
+
// Card Zip Input
|
|
176
|
+
export interface CardZipInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value"> {
|
|
177
|
+
value?: string
|
|
178
|
+
onChange?: (value: string) => void
|
|
179
|
+
format?: "US" | "CA" | "UK" | "other"
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export const CardZipInput = React.forwardRef<HTMLInputElement, CardZipInputProps>(
|
|
183
|
+
({ className, value = "", onChange, format = "US", size, ...props }, ref) => {
|
|
184
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
185
|
+
let rawValue = e.target.value
|
|
186
|
+
|
|
187
|
+
switch (format) {
|
|
188
|
+
case "US":
|
|
189
|
+
rawValue = rawValue.replace(/\D/g, "").slice(0, 5)
|
|
190
|
+
break
|
|
191
|
+
case "CA":
|
|
192
|
+
rawValue = rawValue.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 6)
|
|
193
|
+
if (rawValue.length >= 3) {
|
|
194
|
+
rawValue = rawValue.slice(0, 3) + " " + rawValue.slice(3)
|
|
195
|
+
}
|
|
196
|
+
break
|
|
197
|
+
case "UK":
|
|
198
|
+
rawValue = rawValue.toUpperCase().replace(/[^A-Z0-9\s]/g, "").slice(0, 8)
|
|
199
|
+
break
|
|
200
|
+
default:
|
|
201
|
+
rawValue = rawValue.slice(0, 10)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
onChange?.(rawValue.replace(/\s/g, ""))
|
|
205
|
+
e.target.value = rawValue
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const getPlaceholder = () => {
|
|
209
|
+
switch (format) {
|
|
210
|
+
case "US": return "12345"
|
|
211
|
+
case "CA": return "K1A 0B1"
|
|
212
|
+
case "UK": return "SW1A 1AA"
|
|
213
|
+
default: return "Postal Code"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<Input
|
|
219
|
+
ref={ref}
|
|
220
|
+
type="text"
|
|
221
|
+
autoComplete="postal-code"
|
|
222
|
+
placeholder={getPlaceholder()}
|
|
223
|
+
value={value}
|
|
224
|
+
onChange={handleChange}
|
|
225
|
+
className={className}
|
|
226
|
+
{...props}
|
|
227
|
+
/>
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
)
|
|
231
|
+
CardZipInput.displayName = "CardZipInput"
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import * as React from "react";
|
|
2
4
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
5
|
import { motion, type HTMLMotionProps } from "framer-motion";
|
|
@@ -63,7 +65,7 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
|
|
63
65
|
return (
|
|
64
66
|
<motion.div
|
|
65
67
|
ref={ref}
|
|
66
|
-
className={cn(cardVariants({ variant, size, radius, interactive, className }))}
|
|
68
|
+
className={cn("moonui-theme", cardVariants({ variant, size, radius, interactive, className }))}
|
|
67
69
|
{...interactionProps}
|
|
68
70
|
{...(props as any)}
|
|
69
71
|
/>
|
|
@@ -74,7 +76,7 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
|
|
74
76
|
return (
|
|
75
77
|
<div
|
|
76
78
|
ref={ref}
|
|
77
|
-
className={cn(cardVariants({ variant, size, radius, interactive, className }))}
|
|
79
|
+
className={cn("moonui-theme", cardVariants({ variant, size, radius, interactive, className }))}
|
|
78
80
|
{...props}
|
|
79
81
|
/>
|
|
80
82
|
);
|
|
@@ -88,7 +90,7 @@ const CardHeader = React.forwardRef<
|
|
|
88
90
|
>(({ className, ...props }, ref) => (
|
|
89
91
|
<div
|
|
90
92
|
ref={ref}
|
|
91
|
-
className={cn("flex flex-col space-y-1.5", className)}
|
|
93
|
+
className={cn("moonui-theme", "flex flex-col space-y-1.5", className)}
|
|
92
94
|
{...props}
|
|
93
95
|
/>
|
|
94
96
|
));
|
|
@@ -100,7 +102,7 @@ const CardTitle = React.forwardRef<
|
|
|
100
102
|
>(({ className, ...props }, ref) => (
|
|
101
103
|
<h3
|
|
102
104
|
ref={ref}
|
|
103
|
-
className={cn("text-lg font-semibold leading-none tracking-tight", className)}
|
|
105
|
+
className={cn("moonui-theme", "text-lg font-semibold leading-none tracking-tight", className)}
|
|
104
106
|
{...props}
|
|
105
107
|
/>
|
|
106
108
|
));
|
|
@@ -112,7 +114,7 @@ const CardDescription = React.forwardRef<
|
|
|
112
114
|
>(({ className, ...props }, ref) => (
|
|
113
115
|
<p
|
|
114
116
|
ref={ref}
|
|
115
|
-
className={cn("text-sm text-muted-foreground", className)}
|
|
117
|
+
className={cn("moonui-theme", "text-sm text-muted-foreground", className)}
|
|
116
118
|
{...props}
|
|
117
119
|
/>
|
|
118
120
|
));
|
|
@@ -122,7 +124,7 @@ const CardContent = React.forwardRef<
|
|
|
122
124
|
HTMLDivElement,
|
|
123
125
|
React.HTMLAttributes<HTMLDivElement>
|
|
124
126
|
>(({ className, ...props }, ref) => (
|
|
125
|
-
<div ref={ref} className={cn("pt-0", className)} {...props} />
|
|
127
|
+
<div ref={ref} className={cn("moonui-theme", "pt-0", className)} {...props} />
|
|
126
128
|
));
|
|
127
129
|
CardContent.displayName = "CardContent";
|
|
128
130
|
|
|
@@ -132,7 +134,7 @@ const CardFooter = React.forwardRef<
|
|
|
132
134
|
>(({ className, ...props }, ref) => (
|
|
133
135
|
<div
|
|
134
136
|
ref={ref}
|
|
135
|
-
className={cn("flex items-center pt-4", className)}
|
|
137
|
+
className={cn("moonui-theme", "flex items-center pt-4", className)}
|
|
136
138
|
{...props}
|
|
137
139
|
/>
|
|
138
140
|
));
|
|
@@ -94,7 +94,7 @@ const Checkbox = React.forwardRef<
|
|
|
94
94
|
<CheckboxPrimitive.Root
|
|
95
95
|
ref={ref}
|
|
96
96
|
checked={effectiveChecked}
|
|
97
|
-
className={cn(checkboxVariants({ variant, size, radius, animation }), className)}
|
|
97
|
+
className={cn("moonui-theme", checkboxVariants({ variant, size, radius, animation }), className)}
|
|
98
98
|
{...props}
|
|
99
99
|
>
|
|
100
100
|
<CheckboxPrimitive.Indicator
|
|
@@ -52,7 +52,7 @@ const CollapsibleTrigger = React.forwardRef<
|
|
|
52
52
|
return (
|
|
53
53
|
<CollapsiblePrimitive.Trigger
|
|
54
54
|
ref={ref}
|
|
55
|
-
className={cn(collapsibleTriggerVariants({ variant, size }), className)}
|
|
55
|
+
className={cn("moonui-theme", collapsibleTriggerVariants({ variant, size }), className)}
|
|
56
56
|
asChild={asChild}
|
|
57
57
|
{...props}
|
|
58
58
|
>
|
|
@@ -64,7 +64,7 @@ const CollapsibleTrigger = React.forwardRef<
|
|
|
64
64
|
return (
|
|
65
65
|
<CollapsiblePrimitive.Trigger
|
|
66
66
|
ref={ref}
|
|
67
|
-
className={cn(collapsibleTriggerVariants({ variant, size }), className)}
|
|
67
|
+
className={cn("moonui-theme", collapsibleTriggerVariants({ variant, size }), className)}
|
|
68
68
|
{...props}
|
|
69
69
|
>
|
|
70
70
|
{children}
|
|
@@ -107,7 +107,7 @@ const CollapsibleContent = React.forwardRef<
|
|
|
107
107
|
>(({ className, children, variant, size, ...props }, ref) => (
|
|
108
108
|
<CollapsiblePrimitive.Content
|
|
109
109
|
ref={ref}
|
|
110
|
-
className={cn(collapsibleContentVariants({ variant, size }), className)}
|
|
110
|
+
className={cn("moonui-theme", collapsibleContentVariants({ variant, size }), className)}
|
|
111
111
|
{...props}
|
|
112
112
|
>
|
|
113
113
|
<div className="p-4">{children}</div>
|
|
@@ -574,7 +574,7 @@ export function SimpleColorPicker({
|
|
|
574
574
|
};
|
|
575
575
|
|
|
576
576
|
return (
|
|
577
|
-
<div className={cn("flex flex-wrap gap-2", className)}>
|
|
577
|
+
<div className={cn("moonui-theme", "flex flex-wrap gap-2", className)}>
|
|
578
578
|
{colors.map((color) => (
|
|
579
579
|
<button
|
|
580
580
|
key={color}
|
|
@@ -617,7 +617,7 @@ export function GradientPicker({
|
|
|
617
617
|
};
|
|
618
618
|
|
|
619
619
|
return (
|
|
620
|
-
<div className={cn("space-y-4", className)}>
|
|
620
|
+
<div className={cn("moonui-theme", "space-y-4", className)}>
|
|
621
621
|
<div
|
|
622
622
|
className="h-20 rounded-lg border-2"
|
|
623
623
|
style={{
|
|
@@ -48,7 +48,7 @@ const Command = React.forwardRef<
|
|
|
48
48
|
>(({ className, variant, size, ...props }, ref) => (
|
|
49
49
|
<CommandPrimitive
|
|
50
50
|
ref={ref}
|
|
51
|
-
className={cn(commandVariants({ variant, size }), className)}
|
|
51
|
+
className={cn("moonui-theme", commandVariants({ variant, size }), className)}
|
|
52
52
|
{...props}
|
|
53
53
|
/>
|
|
54
54
|
))
|
|
@@ -112,7 +112,7 @@ const CommandList = React.forwardRef<
|
|
|
112
112
|
>(({ className, ...props }, ref) => (
|
|
113
113
|
<CommandPrimitive.List
|
|
114
114
|
ref={ref}
|
|
115
|
-
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
|
|
115
|
+
className={cn("moonui-theme", "max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
|
|
116
116
|
{...props}
|
|
117
117
|
/>
|
|
118
118
|
))
|
|
@@ -128,7 +128,7 @@ const CommandEmpty = React.forwardRef<
|
|
|
128
128
|
>(({ className, ...props }, ref) => (
|
|
129
129
|
<CommandPrimitive.Empty
|
|
130
130
|
ref={ref}
|
|
131
|
-
className={cn("py-6 text-center text-sm text-muted-foreground", className)}
|
|
131
|
+
className={cn("moonui-theme", "py-6 text-center text-sm text-muted-foreground", className)}
|
|
132
132
|
{...props}
|
|
133
133
|
/>
|
|
134
134
|
))
|
|
@@ -163,7 +163,7 @@ const CommandSeparator = React.forwardRef<
|
|
|
163
163
|
>(({ className, ...props }, ref) => (
|
|
164
164
|
<CommandPrimitive.Separator
|
|
165
165
|
ref={ref}
|
|
166
|
-
className={cn("-mx-1 h-px bg-border", className)}
|
|
166
|
+
className={cn("moonui-theme", "-mx-1 h-px bg-border", className)}
|
|
167
167
|
{...props}
|
|
168
168
|
/>
|
|
169
169
|
))
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
4
|
import { DataTable } from './data-table';
|
|
3
5
|
import { Badge } from './badge';
|
|
@@ -141,7 +143,7 @@ const userColumns: ColumnDef<User>[] = [
|
|
|
141
143
|
cell: ({ row }) => {
|
|
142
144
|
const role = row.getValue('role') as string;
|
|
143
145
|
return (
|
|
144
|
-
<Badge variant={role === 'admin' ? '
|
|
146
|
+
<Badge variant={role === 'admin' ? 'admin' : 'secondary'}>
|
|
145
147
|
{role}
|
|
146
148
|
</Badge>
|
|
147
149
|
);
|
|
@@ -156,7 +158,7 @@ const userColumns: ColumnDef<User>[] = [
|
|
|
156
158
|
<Badge
|
|
157
159
|
variant={
|
|
158
160
|
status === 'active'
|
|
159
|
-
? '
|
|
161
|
+
? 'success'
|
|
160
162
|
: status === 'inactive'
|
|
161
163
|
? 'secondary'
|
|
162
164
|
: 'outline'
|