@moontra/moonui 2.3.6 → 2.3.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui",
3
- "version": "2.3.6",
3
+ "version": "2.3.9",
4
4
  "description": "Premium React component library with modern design and customization",
5
5
  "author": "MoonUI",
6
6
  "license": "MIT",
@@ -15,7 +15,9 @@ const badgeVariants = cva(
15
15
  ["inline-flex items-center justify-center gap-1.5",
16
16
  "font-medium transition-colors duration-200",
17
17
  "border focus:outline-none",
18
- "focus-visible:ring-2 focus-visible:ring-offset-1"],
18
+ "focus-visible:ring-2 focus-visible:ring-offset-1",
19
+ // Auto spacing between badges
20
+ "mr-2 mb-2 last:mr-0"],
19
21
  {
20
22
  variants: {
21
23
  variant: {
@@ -106,6 +108,8 @@ export interface BadgeProps
106
108
  leftIcon?: React.ReactNode;
107
109
  rightIcon?: React.ReactNode;
108
110
  variant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'success' | 'warning' | 'ghost' | 'pro' | 'admin';
111
+ /** Disable automatic spacing between badges */
112
+ noAutoSpacing?: boolean;
109
113
  }
110
114
 
111
115
  /**
@@ -121,6 +125,7 @@ export interface BadgeProps
121
125
  * @param props.onRemove - Kaldırma işlevi
122
126
  * @param props.leftIcon - Badge'in solunda görüntülenecek ikon
123
127
  * @param props.rightIcon - Badge'in sağında görüntülenecek ikon
128
+ * @param props.noAutoSpacing - Otomatik spacing'i devre dışı bırak
124
129
  */
125
130
  function Badge({
126
131
  className,
@@ -133,6 +138,7 @@ function Badge({
133
138
  onRemove,
134
139
  leftIcon,
135
140
  rightIcon,
141
+ noAutoSpacing,
136
142
  children,
137
143
  ...props
138
144
  }: BadgeProps) {
@@ -164,7 +170,13 @@ function Badge({
164
170
 
165
171
  return (
166
172
  <div
167
- className={cn("moonui-theme", badgeVariants({ variant, size, radius }), className)}
173
+ className={cn(
174
+ "moonui-theme",
175
+ badgeVariants({ variant, size, radius }),
176
+ // Remove auto-spacing if noAutoSpacing is true
177
+ noAutoSpacing && "mr-0 mb-0",
178
+ className
179
+ )}
168
180
  data-removable={removable ? "" : undefined}
169
181
  {...props}
170
182
  >
@@ -1,261 +0,0 @@
1
- "use client"
2
-
3
- // Pro Component Wrapper - Simplified Version
4
- // Development: CLI auth required
5
- // Production: License key validation with 24h cache
6
-
7
- import React, { useState, useEffect } from 'react'
8
- import { cn } from '../../lib/utils'
9
- import { Badge } from './badge'
10
- import { Lock, Terminal, AlertCircle } from 'lucide-react'
11
-
12
- interface ProComponentWrapperProps {
13
- children: React.ReactNode
14
- componentId: string
15
- componentName?: string
16
- className?: string
17
- fallback?: React.ReactNode
18
- }
19
-
20
- interface LicenseCache {
21
- timestamp: number
22
- hasProAccess: boolean
23
- }
24
-
25
- const CACHE_KEY = 'moonui_license_cache'
26
- const CACHE_DURATION = 24 * 60 * 60 * 1000 // 24 hours
27
-
28
- export function ProComponentWrapper({
29
- children,
30
- componentId,
31
- componentName,
32
- className,
33
- fallback
34
- }: ProComponentWrapperProps) {
35
- const [state, setState] = useState<{
36
- hasAccess: boolean
37
- loading: boolean
38
- message?: string
39
- }>({
40
- hasAccess: false,
41
- loading: true
42
- })
43
-
44
- useEffect(() => {
45
- // Check if development environment
46
- const isDevelopment = () => {
47
- if (typeof window === 'undefined') return false
48
-
49
- const isLocalhost =
50
- window.location.hostname === 'localhost' ||
51
- window.location.hostname === '127.0.0.1' ||
52
- window.location.hostname.includes('.local')
53
-
54
- const isDevPort =
55
- window.location.port === '3000' ||
56
- window.location.port === '3001' ||
57
- window.location.port === '8080' ||
58
- window.location.port === '5173'
59
-
60
- // Must be localhost with dev port
61
- return process.env.NODE_ENV === 'development' && isLocalhost && isDevPort
62
- }
63
-
64
- // DEVELOPMENT: Check CLI auth
65
- if (isDevelopment()) {
66
- const checkDevAuth = () => {
67
- const cliToken = localStorage.getItem('moonui_cli_token')
68
- const deviceId = localStorage.getItem('moonui_device_id')
69
-
70
- if (!cliToken || !deviceId) {
71
- setState({
72
- hasAccess: false,
73
- loading: false,
74
- message: 'CLI authentication required'
75
- })
76
- return
77
- }
78
-
79
- // Token exists - allow access
80
- setState({
81
- hasAccess: true,
82
- loading: false
83
- })
84
- }
85
-
86
- checkDevAuth()
87
- return
88
- }
89
-
90
- // PRODUCTION: Check license cache
91
- const checkProdLicense = () => {
92
- try {
93
- // Check cache first
94
- const cached = localStorage.getItem(CACHE_KEY)
95
- if (cached) {
96
- const data = JSON.parse(cached) as LicenseCache
97
- const now = Date.now()
98
-
99
- // Cache still valid (24 hours)
100
- if (data.timestamp && (now - data.timestamp) < CACHE_DURATION) {
101
- setState({
102
- hasAccess: data.hasProAccess,
103
- loading: false
104
- })
105
- return
106
- }
107
- }
108
-
109
- // No valid cache - need license key
110
- const licenseKey = process.env.NEXT_PUBLIC_MOONUI_LICENSE_KEY
111
-
112
- if (!licenseKey) {
113
- setState({
114
- hasAccess: false,
115
- loading: false,
116
- message: 'No license key configured'
117
- })
118
- return
119
- }
120
-
121
- // Validate license async
122
- validateLicense(licenseKey).then(result => {
123
- // Save to cache
124
- const cacheData: LicenseCache = {
125
- timestamp: Date.now(),
126
- hasProAccess: result.hasProAccess
127
- }
128
- localStorage.setItem(CACHE_KEY, JSON.stringify(cacheData))
129
-
130
- setState({
131
- hasAccess: result.hasProAccess,
132
- loading: false
133
- })
134
- }).catch(error => {
135
- console.error('License validation failed:', error)
136
-
137
- // Try expired cache as fallback
138
- const cached = localStorage.getItem(CACHE_KEY)
139
- if (cached) {
140
- const data = JSON.parse(cached) as LicenseCache
141
- setState({
142
- hasAccess: data.hasProAccess,
143
- loading: false,
144
- message: 'Using cached license'
145
- })
146
- } else {
147
- setState({
148
- hasAccess: false,
149
- loading: false,
150
- message: 'License validation failed'
151
- })
152
- }
153
- })
154
-
155
- } catch (error) {
156
- console.error('License check error:', error)
157
- setState({
158
- hasAccess: false,
159
- loading: false,
160
- message: 'License check failed'
161
- })
162
- }
163
- }
164
-
165
- checkProdLicense()
166
- }, [])
167
-
168
- // Loading state
169
- if (state.loading) {
170
- return (
171
- <div className={cn("animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-32", className)}>
172
- <div className="flex items-center justify-center h-full">
173
- <div className="text-sm text-gray-500">Loading...</div>
174
- </div>
175
- </div>
176
- )
177
- }
178
-
179
- // Access granted
180
- if (state.hasAccess) {
181
- return <>{children}</>
182
- }
183
-
184
- // Development: Show CLI auth required
185
- if (state.message === 'CLI authentication required') {
186
- return (
187
- <div className={cn("relative", className)}>
188
- <div className="blur-sm grayscale opacity-60 pointer-events-none">
189
- {fallback || children}
190
- </div>
191
- <div className="absolute inset-0 bg-gradient-to-br from-blue-500/10 via-transparent to-purple-500/10 border-2 border-dashed border-blue-400/30 rounded-lg flex items-center justify-center">
192
- <div className="text-center space-y-3 p-6 bg-white/90 dark:bg-gray-900/90 rounded-lg">
193
- <Badge variant="secondary" className="mb-2">
194
- <Terminal className="w-3 h-3 mr-1" />
195
- DEV AUTH REQUIRED
196
- </Badge>
197
- <h3 className="font-semibold">CLI Authentication Required</h3>
198
- <p className="text-sm text-gray-600 dark:text-gray-400 max-w-xs">
199
- Login with MoonUI CLI to use Pro components in development
200
- </p>
201
- <code className="block bg-black text-green-400 p-2 rounded text-xs font-mono">
202
- npx moonui auth login
203
- </code>
204
- </div>
205
- </div>
206
- </div>
207
- )
208
- }
209
-
210
- // Production: Show license required
211
- return (
212
- <div className={cn("relative", className)}>
213
- <div className="blur-sm grayscale opacity-60 pointer-events-none">
214
- {fallback || children}
215
- </div>
216
- <div className="absolute inset-0 bg-gradient-to-br from-amber-500/10 via-transparent to-orange-500/10 border-2 border-dashed border-amber-400/30 rounded-lg flex items-center justify-center">
217
- <div className="text-center space-y-3 p-6 bg-white/90 dark:bg-gray-900/90 rounded-lg">
218
- <Badge variant="destructive" className="mb-2">
219
- <AlertCircle className="w-3 h-3 mr-1" />
220
- LICENSE REQUIRED
221
- </Badge>
222
- <h3 className="font-semibold">{componentName || componentId}</h3>
223
- <p className="text-sm text-gray-600 dark:text-gray-400 max-w-xs">
224
- {state.message || 'Pro license required to use this component'}
225
- </p>
226
- <a
227
- href="https://moonui.dev/pricing"
228
- target="_blank"
229
- rel="noopener noreferrer"
230
- className="inline-block bg-gradient-to-r from-amber-500 to-orange-500 text-white px-4 py-2 rounded-lg text-sm font-medium hover:from-amber-600 hover:to-orange-600 transition-colors"
231
- >
232
- Get Pro License
233
- </a>
234
- </div>
235
- </div>
236
- </div>
237
- )
238
- }
239
-
240
- // Validate license with API
241
- async function validateLicense(licenseKey: string): Promise<{ hasProAccess: boolean }> {
242
- const response = await fetch('/api/v1/license/validate', {
243
- method: 'POST',
244
- headers: {
245
- 'Content-Type': 'application/json'
246
- },
247
- body: JSON.stringify({
248
- licenseKey,
249
- domain: window.location.hostname
250
- })
251
- })
252
-
253
- if (!response.ok) {
254
- throw new Error('License validation failed')
255
- }
256
-
257
- const data = await response.json()
258
- return {
259
- hasProAccess: data.hasProAccess || false
260
- }
261
- }