@moontra/moonui-pro 2.20.0 → 2.20.2
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.ts +691 -261
- package/dist/index.mjs +7419 -4935
- package/package.json +4 -3
- package/scripts/postbuild.js +27 -0
- package/src/components/advanced-chart/index.tsx +5 -1
- package/src/components/advanced-forms/index.tsx +175 -16
- package/src/components/calendar/event-dialog.tsx +18 -13
- package/src/components/calendar/index.tsx +197 -50
- package/src/components/dashboard/dashboard-grid.tsx +21 -3
- package/src/components/dashboard/types.ts +3 -0
- package/src/components/dashboard/widgets/activity-feed.tsx +6 -1
- package/src/components/dashboard/widgets/comparison-widget.tsx +177 -0
- package/src/components/dashboard/widgets/index.ts +5 -0
- package/src/components/dashboard/widgets/metric-card.tsx +21 -1
- package/src/components/dashboard/widgets/progress-widget.tsx +113 -0
- package/src/components/error-boundary/index.tsx +160 -37
- package/src/components/form-wizard/form-wizard-context.tsx +54 -26
- package/src/components/form-wizard/form-wizard-progress.tsx +33 -2
- package/src/components/form-wizard/types.ts +2 -1
- package/src/components/github-stars/hooks.ts +1 -0
- package/src/components/github-stars/variants.tsx +3 -1
- package/src/components/health-check/index.tsx +14 -14
- package/src/components/hover-card-3d/index.tsx +2 -3
- package/src/components/index.ts +5 -3
- package/src/components/kanban/kanban.tsx +23 -18
- package/src/components/license-error/index.tsx +2 -0
- package/src/components/magnetic-button/index.tsx +56 -7
- package/src/components/memory-efficient-data/index.tsx +117 -115
- package/src/components/navbar/index.tsx +781 -0
- package/src/components/performance-debugger/index.tsx +62 -38
- package/src/components/performance-monitor/index.tsx +47 -33
- package/src/components/phone-number-input/index.tsx +32 -27
- package/src/components/phone-number-input/phone-number-input-simple.tsx +167 -0
- package/src/components/rich-text-editor/index.tsx +26 -28
- package/src/components/rich-text-editor/slash-commands-extension.ts +15 -5
- package/src/components/sidebar/index.tsx +32 -13
- package/src/components/timeline/index.tsx +84 -49
- package/src/components/ui/accordion.tsx +550 -42
- package/src/components/ui/avatar.tsx +2 -0
- package/src/components/ui/badge.tsx +2 -0
- package/src/components/ui/breadcrumb.tsx +2 -0
- package/src/components/ui/button.tsx +39 -33
- package/src/components/ui/card.tsx +2 -0
- package/src/components/ui/collapsible.tsx +546 -50
- package/src/components/ui/command.tsx +790 -67
- package/src/components/ui/dialog.tsx +510 -92
- package/src/components/ui/dropdown-menu.tsx +540 -52
- package/src/components/ui/index.ts +37 -5
- package/src/components/ui/input.tsx +2 -0
- package/src/components/ui/magnetic-button.tsx +1 -1
- package/src/components/ui/media-gallery.tsx +1 -2
- package/src/components/ui/navigation-menu.tsx +130 -0
- package/src/components/ui/pagination.tsx +2 -0
- package/src/components/ui/select.tsx +6 -2
- package/src/components/ui/spotlight-card.tsx +1 -1
- package/src/components/ui/table.tsx +2 -0
- package/src/components/ui/tabs-pro.tsx +542 -0
- package/src/components/ui/tabs.tsx +23 -167
- package/src/components/ui/toggle.tsx +13 -13
- package/src/index.ts +11 -3
- package/src/styles/index.css +596 -0
- package/src/use-performance-optimizer.ts +1 -1
- package/src/utils/chart-helpers.ts +1 -1
- package/src/__tests__/use-intersection-observer.test.tsx +0 -216
- package/src/__tests__/use-local-storage.test.tsx +0 -174
- package/src/__tests__/use-pro-access.test.tsx +0 -183
- package/src/components/advanced-chart/advanced-chart.test.tsx +0 -281
- package/src/components/data-table/data-table.test.tsx +0 -187
- package/src/components/enhanced/badge.tsx +0 -191
- package/src/components/enhanced/button.tsx +0 -362
- package/src/components/enhanced/card.tsx +0 -266
- package/src/components/enhanced/dialog.tsx +0 -246
- package/src/components/enhanced/index.ts +0 -4
- package/src/components/file-upload/file-upload.test.tsx +0 -243
- package/src/components/rich-text-editor/index-old-backup.tsx +0 -437
- package/src/types/moonui.d.ts +0 -22
|
@@ -1,33 +1,119 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import * as React from "react"
|
|
4
|
-
import {
|
|
4
|
+
import { useState, useRef, useEffect, useCallback, useMemo } from "react"
|
|
5
|
+
import {
|
|
6
|
+
Search,
|
|
7
|
+
Mic,
|
|
8
|
+
MicOff,
|
|
9
|
+
Clock,
|
|
10
|
+
Sparkles,
|
|
11
|
+
ChevronRight,
|
|
12
|
+
Zap,
|
|
13
|
+
Brain,
|
|
14
|
+
Settings,
|
|
15
|
+
Wand2,
|
|
16
|
+
Bot,
|
|
17
|
+
RefreshCw,
|
|
18
|
+
X,
|
|
19
|
+
Check
|
|
20
|
+
} from "lucide-react"
|
|
5
21
|
import { Command as CommandPrimitive } from "cmdk"
|
|
6
22
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
23
|
+
import { motion, AnimatePresence } from "framer-motion"
|
|
24
|
+
import Fuse from "fuse.js"
|
|
7
25
|
|
|
8
26
|
import { cn } from "../../lib/utils"
|
|
9
|
-
import { Dialog, DialogContent, DialogTitle } from "./dialog"
|
|
27
|
+
import { Dialog, DialogContent, DialogTitle, DialogHeader, DialogDescription } from "./dialog"
|
|
28
|
+
import { Badge } from "./badge"
|
|
29
|
+
import { Button } from "./button"
|
|
30
|
+
import {
|
|
31
|
+
Tooltip,
|
|
32
|
+
TooltipContent,
|
|
33
|
+
TooltipProvider,
|
|
34
|
+
TooltipTrigger
|
|
35
|
+
} from "./tooltip"
|
|
36
|
+
import {
|
|
37
|
+
DropdownMenu,
|
|
38
|
+
DropdownMenuContent,
|
|
39
|
+
DropdownMenuItem,
|
|
40
|
+
DropdownMenuSeparator,
|
|
41
|
+
DropdownMenuTrigger,
|
|
42
|
+
} from "./dropdown-menu"
|
|
43
|
+
import { Input } from "./input"
|
|
44
|
+
import { Label } from "./label"
|
|
45
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select"
|
|
46
|
+
import { createAIProvider, type AIProvider } from "../../lib/ai-providers"
|
|
10
47
|
|
|
11
48
|
/**
|
|
12
|
-
* Command
|
|
49
|
+
* AI-Enhanced Command Palette Component
|
|
13
50
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
51
|
+
* Features:
|
|
52
|
+
* - Fuzzy search with typo tolerance
|
|
53
|
+
* - AI-powered natural language processing
|
|
54
|
+
* - Voice commands with Web Speech API
|
|
55
|
+
* - Smart suggestions based on usage patterns
|
|
56
|
+
* - Intelligent history tracking
|
|
57
|
+
* - Real AI service integration
|
|
16
58
|
*/
|
|
17
59
|
|
|
18
|
-
|
|
60
|
+
// AI Configuration Types
|
|
61
|
+
export interface CommandAIConfig {
|
|
62
|
+
provider?: 'openai' | 'claude' | 'gemini';
|
|
63
|
+
apiKey?: string;
|
|
64
|
+
model?: string;
|
|
65
|
+
temperature?: number;
|
|
66
|
+
maxTokens?: number;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface AISettingsType {
|
|
70
|
+
provider: 'openai' | 'claude' | 'gemini'
|
|
71
|
+
apiKey: string
|
|
72
|
+
model: string
|
|
73
|
+
temperature: number
|
|
74
|
+
maxTokens: number
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Command history interface
|
|
78
|
+
interface CommandHistoryItem {
|
|
79
|
+
id: string
|
|
80
|
+
command: string
|
|
81
|
+
category?: string
|
|
82
|
+
timestamp: number
|
|
83
|
+
frequency: number
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Enhanced command item interface
|
|
87
|
+
export interface CommandItemData {
|
|
88
|
+
id: string
|
|
89
|
+
label: string
|
|
90
|
+
value: string
|
|
91
|
+
category?: string
|
|
92
|
+
keywords?: string[]
|
|
93
|
+
action?: () => void
|
|
94
|
+
shortcut?: string[]
|
|
95
|
+
icon?: React.ReactNode
|
|
96
|
+
priority?: number
|
|
97
|
+
context?: string[]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Command variants with new AI-focused styles
|
|
101
|
+
export const commandVariantsPro = cva(
|
|
19
102
|
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
|
20
103
|
{
|
|
21
104
|
variants: {
|
|
22
105
|
variant: {
|
|
23
106
|
default: "bg-popover text-popover-foreground",
|
|
24
|
-
glass: "bg-background/80 text-foreground backdrop-blur-sm",
|
|
25
|
-
bordered: "bg-popover text-popover-foreground border border-border",
|
|
107
|
+
glass: "bg-background/80 text-foreground backdrop-blur-sm border border-white/10",
|
|
108
|
+
bordered: "bg-popover text-popover-foreground border-2 border-border",
|
|
109
|
+
gradient: "bg-gradient-to-br from-primary/10 via-background to-secondary/10 border border-primary/20",
|
|
110
|
+
neon: "bg-background border-2 border-primary shadow-[0_0_20px_rgba(var(--primary),0.3)]",
|
|
26
111
|
},
|
|
27
112
|
size: {
|
|
28
|
-
sm: "min-h-[
|
|
29
|
-
default: "min-h-[
|
|
30
|
-
lg: "min-h-[
|
|
113
|
+
sm: "min-h-[300px] max-h-[400px]",
|
|
114
|
+
default: "min-h-[400px] max-h-[500px]",
|
|
115
|
+
lg: "min-h-[500px] max-h-[600px]",
|
|
116
|
+
xl: "min-h-[600px] max-h-[700px]",
|
|
31
117
|
},
|
|
32
118
|
},
|
|
33
119
|
defaultVariants: {
|
|
@@ -37,42 +123,689 @@ const MoonUIcommandVariantsPro = cva(
|
|
|
37
123
|
}
|
|
38
124
|
)
|
|
39
125
|
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
126
|
+
// Fuzzy search hook
|
|
127
|
+
const useFuzzySearch = (items: CommandItemData[], query: string, enabled: boolean) => {
|
|
128
|
+
return useMemo(() => {
|
|
129
|
+
if (!enabled || !query) return items
|
|
44
130
|
|
|
45
|
-
const
|
|
131
|
+
const fuse = new Fuse(items, {
|
|
132
|
+
keys: ['label', 'keywords', 'category'],
|
|
133
|
+
threshold: 0.3,
|
|
134
|
+
includeScore: true,
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
return fuse.search(query).map(result => result.item)
|
|
138
|
+
}, [items, query, enabled])
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Command history hook
|
|
142
|
+
const useCommandHistory = (enabled: boolean, maxItems: number = 10) => {
|
|
143
|
+
const [history, setHistory] = useState<CommandHistoryItem[]>([])
|
|
144
|
+
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (!enabled) return
|
|
147
|
+
|
|
148
|
+
const stored = localStorage.getItem('moonui-command-history')
|
|
149
|
+
if (stored) {
|
|
150
|
+
setHistory(JSON.parse(stored))
|
|
151
|
+
}
|
|
152
|
+
}, [enabled])
|
|
153
|
+
|
|
154
|
+
const addToHistory = useCallback((item: CommandItemData) => {
|
|
155
|
+
if (!enabled) return
|
|
156
|
+
|
|
157
|
+
setHistory(prev => {
|
|
158
|
+
const existing = prev.find(h => h.id === item.id)
|
|
159
|
+
let updated: CommandHistoryItem[]
|
|
160
|
+
|
|
161
|
+
if (existing) {
|
|
162
|
+
updated = prev.map(h =>
|
|
163
|
+
h.id === item.id
|
|
164
|
+
? { ...h, timestamp: Date.now(), frequency: h.frequency + 1 }
|
|
165
|
+
: h
|
|
166
|
+
)
|
|
167
|
+
} else {
|
|
168
|
+
updated = [...prev, {
|
|
169
|
+
id: item.id,
|
|
170
|
+
command: item.label,
|
|
171
|
+
category: item.category,
|
|
172
|
+
timestamp: Date.now(),
|
|
173
|
+
frequency: 1,
|
|
174
|
+
}]
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Keep only maxItems
|
|
178
|
+
updated = updated
|
|
179
|
+
.sort((a, b) => b.frequency - a.frequency)
|
|
180
|
+
.slice(0, maxItems)
|
|
181
|
+
|
|
182
|
+
localStorage.setItem('moonui-command-history', JSON.stringify(updated))
|
|
183
|
+
return updated
|
|
184
|
+
})
|
|
185
|
+
}, [enabled, maxItems])
|
|
186
|
+
|
|
187
|
+
return { history, addToHistory }
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Voice command hook
|
|
191
|
+
const useVoiceCommand = (enabled: boolean, onTranscript?: (text: string) => void) => {
|
|
192
|
+
const [isListening, setIsListening] = useState(false)
|
|
193
|
+
const [transcript, setTranscript] = useState('')
|
|
194
|
+
const recognitionRef = useRef<any>(null)
|
|
195
|
+
|
|
196
|
+
useEffect(() => {
|
|
197
|
+
if (!enabled || typeof window === 'undefined') return
|
|
198
|
+
|
|
199
|
+
const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition
|
|
200
|
+
if (!SpeechRecognition) return
|
|
201
|
+
|
|
202
|
+
const recognition = new SpeechRecognition()
|
|
203
|
+
recognition.continuous = false
|
|
204
|
+
recognition.interimResults = false
|
|
205
|
+
recognition.lang = 'en-US'
|
|
206
|
+
|
|
207
|
+
recognition.onresult = (event: any) => {
|
|
208
|
+
const text = event.results[0][0].transcript
|
|
209
|
+
setTranscript(text)
|
|
210
|
+
onTranscript?.(text)
|
|
211
|
+
setIsListening(false)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
recognition.onerror = () => {
|
|
215
|
+
setIsListening(false)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
recognition.onend = () => {
|
|
219
|
+
setIsListening(false)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
recognitionRef.current = recognition
|
|
223
|
+
}, [enabled, onTranscript])
|
|
224
|
+
|
|
225
|
+
const toggleListening = useCallback(() => {
|
|
226
|
+
if (!recognitionRef.current) return
|
|
227
|
+
|
|
228
|
+
if (isListening) {
|
|
229
|
+
recognitionRef.current.stop()
|
|
230
|
+
setIsListening(false)
|
|
231
|
+
} else {
|
|
232
|
+
recognitionRef.current.start()
|
|
233
|
+
setIsListening(true)
|
|
234
|
+
}
|
|
235
|
+
}, [isListening])
|
|
236
|
+
|
|
237
|
+
return { isListening, transcript, toggleListening }
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// AI Suggestions component
|
|
241
|
+
const AISuggestions: React.FC<{
|
|
242
|
+
items: CommandItemData[]
|
|
243
|
+
onSelect: (item: CommandItemData) => void
|
|
244
|
+
history: CommandHistoryItem[]
|
|
245
|
+
}> = ({ items, onSelect, history }) => {
|
|
246
|
+
const suggestions = useMemo(() => {
|
|
247
|
+
// Combine history frequency with item priority
|
|
248
|
+
const scored = items.map(item => {
|
|
249
|
+
const historyItem = history.find(h => h.id === item.id)
|
|
250
|
+
const score = (item.priority || 0) + (historyItem?.frequency || 0) * 2
|
|
251
|
+
return { ...item, score }
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
return scored
|
|
255
|
+
.sort((a, b) => b.score - a.score)
|
|
256
|
+
.slice(0, 3)
|
|
257
|
+
}, [items, history])
|
|
258
|
+
|
|
259
|
+
if (suggestions.length === 0) return null
|
|
260
|
+
|
|
261
|
+
return (
|
|
262
|
+
<div className="px-3 py-2 border-b">
|
|
263
|
+
<div className="flex items-center gap-2 mb-2">
|
|
264
|
+
<Sparkles className="h-3 w-3 text-primary" />
|
|
265
|
+
<span className="text-xs font-medium text-muted-foreground">AI Suggestions</span>
|
|
266
|
+
</div>
|
|
267
|
+
<div className="flex gap-2">
|
|
268
|
+
{suggestions.map(item => (
|
|
269
|
+
<motion.button
|
|
270
|
+
key={item.id}
|
|
271
|
+
initial={{ opacity: 0, scale: 0.9 }}
|
|
272
|
+
animate={{ opacity: 1, scale: 1 }}
|
|
273
|
+
whileHover={{ scale: 1.05 }}
|
|
274
|
+
whileTap={{ scale: 0.95 }}
|
|
275
|
+
onClick={() => onSelect(item)}
|
|
276
|
+
className="flex items-center gap-1 px-2 py-1 text-xs bg-primary/10 hover:bg-primary/20 rounded-md transition-colors"
|
|
277
|
+
>
|
|
278
|
+
{item.icon}
|
|
279
|
+
<span>{item.label}</span>
|
|
280
|
+
</motion.button>
|
|
281
|
+
))}
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Enhanced Command Component Props
|
|
288
|
+
interface CommandProProps
|
|
289
|
+
extends Omit<React.ComponentProps<typeof CommandPrimitive>, 'onSelect'>,
|
|
290
|
+
VariantProps<typeof commandVariantsPro> {
|
|
291
|
+
items?: CommandItemData[]
|
|
292
|
+
onItemSelect?: (item: CommandItemData) => void
|
|
293
|
+
enableAI?: boolean
|
|
294
|
+
enableVoice?: boolean
|
|
295
|
+
enableFuzzySearch?: boolean
|
|
296
|
+
enableAISuggestions?: boolean
|
|
297
|
+
enableHistory?: boolean
|
|
298
|
+
maxHistoryItems?: number
|
|
299
|
+
placeholder?: string
|
|
300
|
+
emptyMessage?: string
|
|
301
|
+
showShortcuts?: boolean
|
|
302
|
+
categories?: string[]
|
|
303
|
+
onVoiceCommand?: (transcript: string) => void
|
|
304
|
+
aiConfig?: CommandAIConfig
|
|
305
|
+
persistAISettings?: boolean
|
|
306
|
+
onAICommand?: (command: string, result: string) => void
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Get AI provider instance
|
|
310
|
+
const getAIProvider = (settings: AISettingsType): AIProvider | null => {
|
|
311
|
+
if (!settings.apiKey) return null;
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
return createAIProvider(settings.provider, {
|
|
315
|
+
apiKey: settings.apiKey,
|
|
316
|
+
model: settings.model,
|
|
317
|
+
temperature: settings.temperature,
|
|
318
|
+
maxTokens: settings.maxTokens
|
|
319
|
+
});
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.error('Failed to create AI provider:', error);
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Main AI-Enhanced Command Component
|
|
327
|
+
export const MoonUICommandPro = React.forwardRef<
|
|
46
328
|
React.ElementRef<typeof CommandPrimitive>,
|
|
47
|
-
|
|
48
|
-
>(({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
329
|
+
CommandProProps
|
|
330
|
+
>(({
|
|
331
|
+
className,
|
|
332
|
+
variant,
|
|
333
|
+
size,
|
|
334
|
+
items = [],
|
|
335
|
+
onItemSelect,
|
|
336
|
+
enableAI = false,
|
|
337
|
+
enableVoice = true,
|
|
338
|
+
enableFuzzySearch = true,
|
|
339
|
+
enableAISuggestions = true,
|
|
340
|
+
enableHistory = true,
|
|
341
|
+
maxHistoryItems = 10,
|
|
342
|
+
placeholder = "Search commands or type...",
|
|
343
|
+
emptyMessage = "No results found.",
|
|
344
|
+
showShortcuts = true,
|
|
345
|
+
categories,
|
|
346
|
+
onVoiceCommand,
|
|
347
|
+
aiConfig = {},
|
|
348
|
+
persistAISettings = true,
|
|
349
|
+
onAICommand,
|
|
350
|
+
...props
|
|
351
|
+
}, ref) => {
|
|
352
|
+
const [search, setSearch] = useState('')
|
|
353
|
+
const [selectedCategory, setSelectedCategory] = useState<string | null>(null)
|
|
354
|
+
const [isAISettingsOpen, setIsAISettingsOpen] = useState(false)
|
|
355
|
+
const [isProcessing, setIsProcessing] = useState(false)
|
|
356
|
+
|
|
357
|
+
// AI Settings
|
|
358
|
+
const [aiSettings, setAiSettings] = useState<AISettingsType>(() => {
|
|
359
|
+
if (persistAISettings && typeof window !== 'undefined') {
|
|
360
|
+
try {
|
|
361
|
+
const stored = localStorage.getItem('moonui-ai-settings');
|
|
362
|
+
if (stored) {
|
|
363
|
+
const parsed = JSON.parse(stored);
|
|
364
|
+
return {
|
|
365
|
+
provider: (aiConfig.provider !== undefined ? aiConfig.provider : parsed.provider || 'openai') as 'openai' | 'claude' | 'gemini',
|
|
366
|
+
apiKey: aiConfig.apiKey !== undefined ? aiConfig.apiKey : parsed.apiKey || '',
|
|
367
|
+
model: aiConfig.model !== undefined ? aiConfig.model : parsed.model || 'gpt-3.5-turbo',
|
|
368
|
+
temperature: aiConfig.temperature !== undefined ? aiConfig.temperature : parsed.temperature ?? 0.7,
|
|
369
|
+
maxTokens: aiConfig.maxTokens !== undefined ? aiConfig.maxTokens : parsed.maxTokens ?? 1000,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
} catch (e) {
|
|
373
|
+
console.error('Failed to load AI settings from localStorage:', e);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return {
|
|
378
|
+
provider: (aiConfig.provider || 'openai') as 'openai' | 'claude' | 'gemini',
|
|
379
|
+
apiKey: aiConfig.apiKey || '',
|
|
380
|
+
model: aiConfig.model || 'gpt-3.5-turbo',
|
|
381
|
+
temperature: aiConfig.temperature ?? 0.7,
|
|
382
|
+
maxTokens: aiConfig.maxTokens ?? 1000,
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
const { history, addToHistory } = useCommandHistory(enableHistory, maxHistoryItems)
|
|
387
|
+
const { isListening, transcript, toggleListening } = useVoiceCommand(enableVoice && enableAI, (text) => {
|
|
388
|
+
setSearch(text)
|
|
389
|
+
onVoiceCommand?.(text)
|
|
390
|
+
if (enableAI) {
|
|
391
|
+
handleNaturalLanguageCommand(text)
|
|
392
|
+
}
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
// Filter items by category
|
|
396
|
+
const filteredByCategory = useMemo(() => {
|
|
397
|
+
if (!selectedCategory) return items
|
|
398
|
+
return items.filter(item => item.category === selectedCategory)
|
|
399
|
+
}, [items, selectedCategory])
|
|
400
|
+
|
|
401
|
+
// Apply fuzzy search
|
|
402
|
+
const searchResults = useFuzzySearch(filteredByCategory, search, enableFuzzySearch)
|
|
403
|
+
|
|
404
|
+
// Natural language command processing
|
|
405
|
+
const handleNaturalLanguageCommand = async (text: string) => {
|
|
406
|
+
if (!enableAI || !aiSettings.apiKey || isProcessing) return
|
|
407
|
+
|
|
408
|
+
setIsProcessing(true)
|
|
409
|
+
try {
|
|
410
|
+
const provider = getAIProvider(aiSettings)
|
|
411
|
+
if (!provider) {
|
|
412
|
+
throw new Error('Failed to initialize AI provider')
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Process natural language command
|
|
416
|
+
const prompt = `Convert this natural language command to a specific action: "${text}".
|
|
417
|
+
Available commands: ${items.map(item => item.label).join(', ')}.
|
|
418
|
+
Respond with just the closest matching command name, nothing else.`
|
|
419
|
+
|
|
420
|
+
const result = await provider.generateText(prompt)
|
|
421
|
+
|
|
422
|
+
// Find matching command
|
|
423
|
+
const matchingCommand = items.find(item =>
|
|
424
|
+
item.label.toLowerCase().includes(result.toLowerCase()) ||
|
|
425
|
+
result.toLowerCase().includes(item.label.toLowerCase())
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
if (matchingCommand) {
|
|
429
|
+
handleSelect(matchingCommand)
|
|
430
|
+
onAICommand?.(text, matchingCommand.label)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
} catch (error) {
|
|
434
|
+
console.error('Natural language processing error:', error)
|
|
435
|
+
} finally {
|
|
436
|
+
setIsProcessing(false)
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Handle item selection
|
|
441
|
+
const handleSelect = useCallback((item: CommandItemData) => {
|
|
442
|
+
addToHistory(item)
|
|
443
|
+
item.action?.()
|
|
444
|
+
onItemSelect?.(item)
|
|
445
|
+
}, [addToHistory, onItemSelect])
|
|
446
|
+
|
|
447
|
+
// Group items by category
|
|
448
|
+
const groupedItems = useMemo(() => {
|
|
449
|
+
const groups: Record<string, CommandItemData[]> = {}
|
|
450
|
+
|
|
451
|
+
searchResults.forEach(item => {
|
|
452
|
+
const category = item.category || 'Other'
|
|
453
|
+
if (!groups[category]) groups[category] = []
|
|
454
|
+
groups[category].push(item)
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
return groups
|
|
458
|
+
}, [searchResults])
|
|
459
|
+
|
|
460
|
+
return (
|
|
461
|
+
<>
|
|
462
|
+
<CommandPrimitive
|
|
463
|
+
ref={ref}
|
|
464
|
+
className={cn(commandVariantsPro({ variant, size }), className)}
|
|
465
|
+
{...props}
|
|
466
|
+
>
|
|
467
|
+
{/* Search Input with Voice and AI */}
|
|
468
|
+
<div className="flex items-center border-b px-3">
|
|
469
|
+
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
|
470
|
+
<CommandPrimitive.Input
|
|
471
|
+
value={search}
|
|
472
|
+
onValueChange={setSearch}
|
|
473
|
+
onKeyDown={(e) => {
|
|
474
|
+
if (e.key === 'Enter' && enableAI && search) {
|
|
475
|
+
e.preventDefault()
|
|
476
|
+
handleNaturalLanguageCommand(search)
|
|
477
|
+
}
|
|
478
|
+
}}
|
|
479
|
+
className="flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
|
480
|
+
placeholder={placeholder}
|
|
481
|
+
/>
|
|
482
|
+
|
|
483
|
+
{/* Voice Command Button */}
|
|
484
|
+
{enableVoice && enableAI && (
|
|
485
|
+
<TooltipProvider>
|
|
486
|
+
<Tooltip>
|
|
487
|
+
<TooltipTrigger asChild>
|
|
488
|
+
<Button
|
|
489
|
+
variant="ghost"
|
|
490
|
+
size="sm"
|
|
491
|
+
onClick={toggleListening}
|
|
492
|
+
className={cn(
|
|
493
|
+
"ml-2",
|
|
494
|
+
isListening && "text-primary animate-pulse"
|
|
495
|
+
)}
|
|
496
|
+
>
|
|
497
|
+
{isListening ? (
|
|
498
|
+
<Mic className="h-4 w-4" />
|
|
499
|
+
) : (
|
|
500
|
+
<MicOff className="h-4 w-4" />
|
|
501
|
+
)}
|
|
502
|
+
</Button>
|
|
503
|
+
</TooltipTrigger>
|
|
504
|
+
<TooltipContent>
|
|
505
|
+
{isListening ? "Listening..." : "Voice command"}
|
|
506
|
+
</TooltipContent>
|
|
507
|
+
</Tooltip>
|
|
508
|
+
</TooltipProvider>
|
|
509
|
+
)}
|
|
510
|
+
|
|
511
|
+
{/* AI Settings Button */}
|
|
512
|
+
{enableAI && (
|
|
513
|
+
<TooltipProvider>
|
|
514
|
+
<Tooltip>
|
|
515
|
+
<TooltipTrigger asChild>
|
|
516
|
+
<Button
|
|
517
|
+
variant="ghost"
|
|
518
|
+
size="sm"
|
|
519
|
+
onClick={() => setIsAISettingsOpen(true)}
|
|
520
|
+
className="ml-1"
|
|
521
|
+
>
|
|
522
|
+
<Settings className="h-4 w-4" />
|
|
523
|
+
</Button>
|
|
524
|
+
</TooltipTrigger>
|
|
525
|
+
<TooltipContent>
|
|
526
|
+
AI Settings
|
|
527
|
+
</TooltipContent>
|
|
528
|
+
</Tooltip>
|
|
529
|
+
</TooltipProvider>
|
|
530
|
+
)}
|
|
531
|
+
</div>
|
|
532
|
+
|
|
533
|
+
{/* Category Filters */}
|
|
534
|
+
{categories && categories.length > 0 && (
|
|
535
|
+
<div className="flex gap-2 px-3 py-2 border-b">
|
|
536
|
+
<Button
|
|
537
|
+
variant={selectedCategory === null ? "primary" : "outline"}
|
|
538
|
+
size="sm"
|
|
539
|
+
onClick={() => setSelectedCategory(null)}
|
|
540
|
+
className="h-7 text-xs"
|
|
541
|
+
>
|
|
542
|
+
All
|
|
543
|
+
</Button>
|
|
544
|
+
{categories.map(cat => (
|
|
545
|
+
<Button
|
|
546
|
+
key={cat}
|
|
547
|
+
variant={selectedCategory === cat ? "primary" : "outline"}
|
|
548
|
+
size="sm"
|
|
549
|
+
onClick={() => setSelectedCategory(cat)}
|
|
550
|
+
className="h-7 text-xs"
|
|
551
|
+
>
|
|
552
|
+
{cat}
|
|
553
|
+
</Button>
|
|
554
|
+
))}
|
|
555
|
+
</div>
|
|
556
|
+
)}
|
|
557
|
+
|
|
558
|
+
{/* AI Suggestions */}
|
|
559
|
+
{enableAI && enableAISuggestions && !search && (
|
|
560
|
+
<AISuggestions
|
|
561
|
+
items={items}
|
|
562
|
+
onSelect={handleSelect}
|
|
563
|
+
history={history}
|
|
564
|
+
/>
|
|
565
|
+
)}
|
|
566
|
+
|
|
567
|
+
{/* Recent Commands */}
|
|
568
|
+
{enableHistory && history.length > 0 && !search && (
|
|
569
|
+
<div className="px-3 py-2 border-b">
|
|
570
|
+
<div className="flex items-center gap-2 mb-2">
|
|
571
|
+
<Clock className="h-3 w-3 text-muted-foreground" />
|
|
572
|
+
<span className="text-xs font-medium text-muted-foreground">Recent Commands</span>
|
|
573
|
+
</div>
|
|
574
|
+
<div className="space-y-1">
|
|
575
|
+
{history.slice(0, 3).map(item => (
|
|
576
|
+
<button
|
|
577
|
+
key={item.id}
|
|
578
|
+
onClick={() => {
|
|
579
|
+
const cmd = items.find(i => i.id === item.id)
|
|
580
|
+
if (cmd) handleSelect(cmd)
|
|
581
|
+
}}
|
|
582
|
+
className="flex items-center justify-between w-full px-2 py-1 text-xs hover:bg-accent rounded-sm transition-colors"
|
|
583
|
+
>
|
|
584
|
+
<span>{item.command}</span>
|
|
585
|
+
{item.category && (
|
|
586
|
+
<Badge variant="outline" className="text-[10px] h-4">
|
|
587
|
+
{item.category}
|
|
588
|
+
</Badge>
|
|
589
|
+
)}
|
|
590
|
+
</button>
|
|
591
|
+
))}
|
|
592
|
+
</div>
|
|
593
|
+
</div>
|
|
594
|
+
)}
|
|
595
|
+
|
|
596
|
+
{/* Command List */}
|
|
597
|
+
<CommandPrimitive.List className="max-h-[300px] overflow-y-auto overflow-x-hidden p-2">
|
|
598
|
+
{searchResults.length === 0 ? (
|
|
599
|
+
<CommandPrimitive.Empty className="py-6 text-center text-sm text-muted-foreground">
|
|
600
|
+
{emptyMessage}
|
|
601
|
+
</CommandPrimitive.Empty>
|
|
602
|
+
) : (
|
|
603
|
+
<AnimatePresence>
|
|
604
|
+
{Object.entries(groupedItems).map(([category, categoryItems]) => (
|
|
605
|
+
<motion.div
|
|
606
|
+
key={category}
|
|
607
|
+
initial={{ opacity: 0, y: 10 }}
|
|
608
|
+
animate={{ opacity: 1, y: 0 }}
|
|
609
|
+
exit={{ opacity: 0, y: -10 }}
|
|
610
|
+
>
|
|
611
|
+
<CommandPrimitive.Group
|
|
612
|
+
heading={category}
|
|
613
|
+
className="overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground"
|
|
614
|
+
>
|
|
615
|
+
{categoryItems.map(item => (
|
|
616
|
+
<CommandPrimitive.Item
|
|
617
|
+
key={item.id}
|
|
618
|
+
value={item.value}
|
|
619
|
+
onSelect={() => handleSelect(item)}
|
|
620
|
+
className="relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50"
|
|
621
|
+
>
|
|
622
|
+
<div className="flex items-center gap-2 flex-1">
|
|
623
|
+
{item.icon && (
|
|
624
|
+
<span className="shrink-0">{item.icon}</span>
|
|
625
|
+
)}
|
|
626
|
+
<span>{item.label}</span>
|
|
627
|
+
</div>
|
|
628
|
+
{showShortcuts && item.shortcut && (
|
|
629
|
+
<div className="ml-auto flex gap-0.5">
|
|
630
|
+
{item.shortcut.map((key, i) => (
|
|
631
|
+
<kbd
|
|
632
|
+
key={i}
|
|
633
|
+
className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100"
|
|
634
|
+
>
|
|
635
|
+
{key}
|
|
636
|
+
</kbd>
|
|
637
|
+
))}
|
|
638
|
+
</div>
|
|
639
|
+
)}
|
|
640
|
+
</CommandPrimitive.Item>
|
|
641
|
+
))}
|
|
642
|
+
</CommandPrimitive.Group>
|
|
643
|
+
</motion.div>
|
|
644
|
+
))}
|
|
645
|
+
</AnimatePresence>
|
|
646
|
+
)}
|
|
647
|
+
</CommandPrimitive.List>
|
|
648
|
+
|
|
649
|
+
{/* AI Processing Indicator */}
|
|
650
|
+
{isProcessing && (
|
|
651
|
+
<div className="px-3 py-2 border-t">
|
|
652
|
+
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
|
653
|
+
<RefreshCw className="h-3 w-3 animate-spin" />
|
|
654
|
+
<span>Processing natural language command...</span>
|
|
655
|
+
</div>
|
|
656
|
+
</div>
|
|
657
|
+
)}
|
|
658
|
+
|
|
659
|
+
{/* Natural Language Hint */}
|
|
660
|
+
{enableAI && (
|
|
661
|
+
<div className="px-3 py-2 border-t">
|
|
662
|
+
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
|
663
|
+
<Zap className="h-3 w-3" />
|
|
664
|
+
<span>Tip: You can use natural language commands like "open settings"</span>
|
|
665
|
+
</div>
|
|
666
|
+
</div>
|
|
667
|
+
)}
|
|
668
|
+
</CommandPrimitive>
|
|
669
|
+
|
|
670
|
+
{/* AI Settings Modal */}
|
|
671
|
+
{enableAI && (
|
|
672
|
+
<Dialog open={isAISettingsOpen} onOpenChange={setIsAISettingsOpen}>
|
|
673
|
+
<DialogContent className="sm:max-w-[425px]">
|
|
674
|
+
<DialogHeader>
|
|
675
|
+
<DialogTitle>AI Settings</DialogTitle>
|
|
676
|
+
<DialogDescription>
|
|
677
|
+
Configure your AI provider and API settings for enhanced command processing.
|
|
678
|
+
</DialogDescription>
|
|
679
|
+
</DialogHeader>
|
|
680
|
+
<div className="grid gap-4 py-4">
|
|
681
|
+
<div className="grid gap-2">
|
|
682
|
+
<Label htmlFor="provider">Provider</Label>
|
|
683
|
+
<Select
|
|
684
|
+
value={aiSettings.provider}
|
|
685
|
+
onValueChange={(value: 'openai' | 'claude' | 'gemini') => {
|
|
686
|
+
const defaultModels = {
|
|
687
|
+
openai: 'gpt-3.5-turbo',
|
|
688
|
+
claude: 'claude-3-sonnet-20240229',
|
|
689
|
+
gemini: 'gemini-2.0-flash'
|
|
690
|
+
};
|
|
691
|
+
const newSettings = {
|
|
692
|
+
...aiSettings,
|
|
693
|
+
provider: value,
|
|
694
|
+
model: defaultModels[value] || 'gpt-3.5-turbo'
|
|
695
|
+
};
|
|
696
|
+
setAiSettings(newSettings);
|
|
697
|
+
if (persistAISettings) {
|
|
698
|
+
localStorage.setItem('moonui-ai-settings', JSON.stringify(newSettings));
|
|
699
|
+
}
|
|
700
|
+
}}
|
|
701
|
+
>
|
|
702
|
+
<SelectTrigger>
|
|
703
|
+
<SelectValue />
|
|
704
|
+
</SelectTrigger>
|
|
705
|
+
<SelectContent>
|
|
706
|
+
<SelectItem value="openai">OpenAI</SelectItem>
|
|
707
|
+
<SelectItem value="claude">Claude (Anthropic)</SelectItem>
|
|
708
|
+
<SelectItem value="gemini">Gemini (Google)</SelectItem>
|
|
709
|
+
</SelectContent>
|
|
710
|
+
</Select>
|
|
711
|
+
</div>
|
|
712
|
+
<div className="grid gap-2">
|
|
713
|
+
<Label htmlFor="apiKey">API Key</Label>
|
|
714
|
+
<Input
|
|
715
|
+
id="apiKey"
|
|
716
|
+
type="password"
|
|
717
|
+
value={aiSettings.apiKey}
|
|
718
|
+
onChange={(e) => {
|
|
719
|
+
const newSettings = { ...aiSettings, apiKey: e.target.value };
|
|
720
|
+
setAiSettings(newSettings);
|
|
721
|
+
if (persistAISettings) {
|
|
722
|
+
localStorage.setItem('moonui-ai-settings', JSON.stringify(newSettings));
|
|
723
|
+
}
|
|
724
|
+
}}
|
|
725
|
+
placeholder="sk-..."
|
|
726
|
+
/>
|
|
727
|
+
</div>
|
|
728
|
+
<div className="grid gap-2">
|
|
729
|
+
<Label htmlFor="model">Model</Label>
|
|
730
|
+
<Select
|
|
731
|
+
value={aiSettings.model}
|
|
732
|
+
onValueChange={(value) => {
|
|
733
|
+
const newSettings = { ...aiSettings, model: value };
|
|
734
|
+
setAiSettings(newSettings);
|
|
735
|
+
if (persistAISettings) {
|
|
736
|
+
localStorage.setItem('moonui-ai-settings', JSON.stringify(newSettings));
|
|
737
|
+
}
|
|
738
|
+
}}
|
|
739
|
+
>
|
|
740
|
+
<SelectTrigger>
|
|
741
|
+
<SelectValue />
|
|
742
|
+
</SelectTrigger>
|
|
743
|
+
<SelectContent>
|
|
744
|
+
{aiSettings.provider === 'openai' && (
|
|
745
|
+
<>
|
|
746
|
+
<SelectItem value="gpt-4">GPT-4</SelectItem>
|
|
747
|
+
<SelectItem value="gpt-3.5-turbo">GPT-3.5 Turbo</SelectItem>
|
|
748
|
+
</>
|
|
749
|
+
)}
|
|
750
|
+
{aiSettings.provider === 'claude' && (
|
|
751
|
+
<>
|
|
752
|
+
<SelectItem value="claude-3-opus">Claude 3 Opus</SelectItem>
|
|
753
|
+
<SelectItem value="claude-3-sonnet">Claude 3 Sonnet</SelectItem>
|
|
754
|
+
<SelectItem value="claude-3-haiku">Claude 3 Haiku</SelectItem>
|
|
755
|
+
</>
|
|
756
|
+
)}
|
|
757
|
+
{aiSettings.provider === 'gemini' && (
|
|
758
|
+
<>
|
|
759
|
+
<SelectItem value="gemini-2.0-flash">Gemini 2.0 Flash</SelectItem>
|
|
760
|
+
<SelectItem value="gemini-1.5-flash">Gemini 1.5 Flash</SelectItem>
|
|
761
|
+
<SelectItem value="gemini-1.5-pro">Gemini 1.5 Pro</SelectItem>
|
|
762
|
+
</>
|
|
763
|
+
)}
|
|
764
|
+
{false && (
|
|
765
|
+
<>
|
|
766
|
+
<SelectItem value="command">Command</SelectItem>
|
|
767
|
+
<SelectItem value="command-light">Command Light</SelectItem>
|
|
768
|
+
</>
|
|
769
|
+
)}
|
|
770
|
+
</SelectContent>
|
|
771
|
+
</Select>
|
|
772
|
+
</div>
|
|
773
|
+
</div>
|
|
774
|
+
<div className="flex justify-end gap-2">
|
|
775
|
+
<Button
|
|
776
|
+
variant="outline"
|
|
777
|
+
onClick={() => setIsAISettingsOpen(false)}
|
|
778
|
+
>
|
|
779
|
+
Cancel
|
|
780
|
+
</Button>
|
|
781
|
+
<Button onClick={() => setIsAISettingsOpen(false)}>
|
|
782
|
+
Save Settings
|
|
783
|
+
</Button>
|
|
784
|
+
</div>
|
|
785
|
+
</DialogContent>
|
|
786
|
+
</Dialog>
|
|
787
|
+
)}
|
|
788
|
+
</>
|
|
789
|
+
)
|
|
790
|
+
})
|
|
55
791
|
MoonUICommandPro.displayName = CommandPrimitive.displayName
|
|
56
792
|
|
|
57
|
-
//
|
|
58
|
-
interface
|
|
59
|
-
|
|
793
|
+
// Enhanced Dialog wrapper for AI Command
|
|
794
|
+
interface CommandDialogProProps extends React.ComponentProps<typeof Dialog> {
|
|
795
|
+
commandProps?: CommandProProps
|
|
60
796
|
children?: React.ReactNode
|
|
61
797
|
}
|
|
62
798
|
|
|
63
|
-
const MoonUICommandDialogPro = ({
|
|
799
|
+
export const MoonUICommandDialogPro = ({
|
|
64
800
|
children,
|
|
65
|
-
|
|
801
|
+
commandProps,
|
|
66
802
|
...props
|
|
67
|
-
}:
|
|
803
|
+
}: CommandDialogProProps) => {
|
|
68
804
|
return (
|
|
69
805
|
<Dialog {...props}>
|
|
70
|
-
<DialogContent className="overflow-hidden p-0 shadow-
|
|
71
|
-
<DialogTitle className="sr-only">Command Menu</DialogTitle>
|
|
72
|
-
<MoonUICommandPro
|
|
73
|
-
"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5",
|
|
74
|
-
commandClassName
|
|
75
|
-
)}>
|
|
806
|
+
<DialogContent className="overflow-hidden p-0 shadow-2xl" hideCloseButton>
|
|
807
|
+
<DialogTitle className="sr-only">AI Command Menu</DialogTitle>
|
|
808
|
+
<MoonUICommandPro {...commandProps}>
|
|
76
809
|
{children}
|
|
77
810
|
</MoonUICommandPro>
|
|
78
811
|
</DialogContent>
|
|
@@ -80,11 +813,11 @@ const MoonUICommandDialogPro = ({
|
|
|
80
813
|
)
|
|
81
814
|
}
|
|
82
815
|
|
|
83
|
-
//
|
|
816
|
+
// Basic Command Components (for backward compatibility)
|
|
84
817
|
interface CommandInputProps
|
|
85
818
|
extends React.ComponentProps<typeof CommandPrimitive.Input> {}
|
|
86
819
|
|
|
87
|
-
const MoonUICommandInputPro = React.forwardRef<
|
|
820
|
+
export const MoonUICommandInputPro = React.forwardRef<
|
|
88
821
|
React.ElementRef<typeof CommandPrimitive.Input>,
|
|
89
822
|
CommandInputProps
|
|
90
823
|
>(({ className, ...props }, ref) => (
|
|
@@ -102,11 +835,10 @@ const MoonUICommandInputPro = React.forwardRef<
|
|
|
102
835
|
))
|
|
103
836
|
MoonUICommandInputPro.displayName = CommandPrimitive.Input.displayName
|
|
104
837
|
|
|
105
|
-
// CommandList bileşeni
|
|
106
838
|
interface CommandListProps
|
|
107
839
|
extends React.ComponentProps<typeof CommandPrimitive.List> {}
|
|
108
840
|
|
|
109
|
-
const MoonUICommandListPro = React.forwardRef<
|
|
841
|
+
export const MoonUICommandListPro = React.forwardRef<
|
|
110
842
|
React.ElementRef<typeof CommandPrimitive.List>,
|
|
111
843
|
CommandListProps
|
|
112
844
|
>(({ className, ...props }, ref) => (
|
|
@@ -118,11 +850,10 @@ const MoonUICommandListPro = React.forwardRef<
|
|
|
118
850
|
))
|
|
119
851
|
MoonUICommandListPro.displayName = CommandPrimitive.List.displayName
|
|
120
852
|
|
|
121
|
-
// CommandEmpty bileşeni
|
|
122
853
|
interface CommandEmptyProps
|
|
123
854
|
extends React.ComponentProps<typeof CommandPrimitive.Empty> {}
|
|
124
855
|
|
|
125
|
-
const MoonUICommandEmptyPro = React.forwardRef<
|
|
856
|
+
export const MoonUICommandEmptyPro = React.forwardRef<
|
|
126
857
|
React.ElementRef<typeof CommandPrimitive.Empty>,
|
|
127
858
|
CommandEmptyProps
|
|
128
859
|
>(({ className, ...props }, ref) => (
|
|
@@ -134,11 +865,10 @@ const MoonUICommandEmptyPro = React.forwardRef<
|
|
|
134
865
|
))
|
|
135
866
|
MoonUICommandEmptyPro.displayName = CommandPrimitive.Empty.displayName
|
|
136
867
|
|
|
137
|
-
// CommandGroup bileşeni
|
|
138
868
|
interface CommandGroupProps
|
|
139
869
|
extends React.ComponentProps<typeof CommandPrimitive.Group> {}
|
|
140
870
|
|
|
141
|
-
const MoonUICommandGroupPro = React.forwardRef<
|
|
871
|
+
export const MoonUICommandGroupPro = React.forwardRef<
|
|
142
872
|
React.ElementRef<typeof CommandPrimitive.Group>,
|
|
143
873
|
CommandGroupProps
|
|
144
874
|
>(({ className, ...props }, ref) => (
|
|
@@ -153,11 +883,10 @@ const MoonUICommandGroupPro = React.forwardRef<
|
|
|
153
883
|
))
|
|
154
884
|
MoonUICommandGroupPro.displayName = CommandPrimitive.Group.displayName
|
|
155
885
|
|
|
156
|
-
// CommandSeparator bileşeni
|
|
157
886
|
interface CommandSeparatorProps
|
|
158
887
|
extends React.ComponentProps<typeof CommandPrimitive.Separator> {}
|
|
159
888
|
|
|
160
|
-
const MoonUICommandSeparatorPro = React.forwardRef<
|
|
889
|
+
export const MoonUICommandSeparatorPro = React.forwardRef<
|
|
161
890
|
React.ElementRef<typeof CommandPrimitive.Separator>,
|
|
162
891
|
CommandSeparatorProps
|
|
163
892
|
>(({ className, ...props }, ref) => (
|
|
@@ -169,11 +898,10 @@ const MoonUICommandSeparatorPro = React.forwardRef<
|
|
|
169
898
|
))
|
|
170
899
|
MoonUICommandSeparatorPro.displayName = CommandPrimitive.Separator.displayName
|
|
171
900
|
|
|
172
|
-
// CommandItem bileşeni
|
|
173
901
|
interface CommandItemProps
|
|
174
902
|
extends React.ComponentProps<typeof CommandPrimitive.Item> {}
|
|
175
903
|
|
|
176
|
-
const MoonUICommandItemPro = React.forwardRef<
|
|
904
|
+
export const MoonUICommandItemPro = React.forwardRef<
|
|
177
905
|
React.ElementRef<typeof CommandPrimitive.Item>,
|
|
178
906
|
CommandItemProps
|
|
179
907
|
>(({ className, ...props }, ref) => (
|
|
@@ -188,8 +916,7 @@ const MoonUICommandItemPro = React.forwardRef<
|
|
|
188
916
|
))
|
|
189
917
|
MoonUICommandItemPro.displayName = CommandPrimitive.Item.displayName
|
|
190
918
|
|
|
191
|
-
|
|
192
|
-
const MoonUICommandShortcutPro = ({
|
|
919
|
+
export const MoonUICommandShortcutPro = ({
|
|
193
920
|
className,
|
|
194
921
|
...props
|
|
195
922
|
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
@@ -205,21 +932,17 @@ const MoonUICommandShortcutPro = ({
|
|
|
205
932
|
}
|
|
206
933
|
MoonUICommandShortcutPro.displayName = "CommandShortcutPro"
|
|
207
934
|
|
|
935
|
+
// Additional exports for convenience
|
|
936
|
+
export {
|
|
937
|
+
commandVariantsPro as commandVariants,
|
|
938
|
+
MoonUICommandPro as Command,
|
|
939
|
+
MoonUICommandDialogPro as CommandDialog,
|
|
940
|
+
MoonUICommandInputPro as CommandInput,
|
|
941
|
+
MoonUICommandListPro as CommandList,
|
|
942
|
+
MoonUICommandEmptyPro as CommandEmpty,
|
|
943
|
+
MoonUICommandGroupPro as CommandGroup,
|
|
944
|
+
MoonUICommandSeparatorPro as CommandSeparator,
|
|
945
|
+
MoonUICommandItemPro as CommandItem,
|
|
946
|
+
MoonUICommandShortcutPro as CommandShortcut
|
|
947
|
+
}
|
|
208
948
|
|
|
209
|
-
// Internal aliases for Pro component usage
|
|
210
|
-
export const commandVariantsInternal = MoonUIcommandVariantsPro
|
|
211
|
-
export const CommandInternal = MoonUICommandPro
|
|
212
|
-
export const CommandDialogInternal = MoonUICommandDialogPro
|
|
213
|
-
export const CommandInputInternal = MoonUICommandInputPro
|
|
214
|
-
export const CommandListInternal = MoonUICommandListPro
|
|
215
|
-
export const CommandEmptyInternal = MoonUICommandEmptyPro
|
|
216
|
-
export const CommandGroupInternal = MoonUICommandGroupPro
|
|
217
|
-
export const CommandSeparatorInternal = MoonUICommandSeparatorPro
|
|
218
|
-
export const CommandItemInternal = MoonUICommandItemPro
|
|
219
|
-
export const CommandShortcutInternal = MoonUICommandShortcutPro
|
|
220
|
-
|
|
221
|
-
// Pro exports
|
|
222
|
-
export { MoonUIcommandVariantsPro, MoonUICommandPro, MoonUICommandDialogPro, MoonUICommandInputPro, MoonUICommandListPro, MoonUICommandEmptyPro, MoonUICommandGroupPro, MoonUICommandSeparatorPro, MoonUICommandItemPro, MoonUICommandShortcutPro }
|
|
223
|
-
|
|
224
|
-
// Clean exports (without MoonUI prefix for easier usage)
|
|
225
|
-
export { MoonUIcommandVariantsPro as commandVariants, MoonUICommandPro as Command, MoonUICommandDialogPro as CommandDialog, MoonUICommandInputPro as CommandInput, MoonUICommandListPro as CommandList, MoonUICommandEmptyPro as CommandEmpty, MoonUICommandGroupPro as CommandGroup, MoonUICommandSeparatorPro as CommandSeparator, MoonUICommandItemPro as CommandItem, MoonUICommandShortcutPro as CommandShortcut }
|