@moontra/moonui-pro 2.11.4 → 2.12.0

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-pro",
3
- "version": "2.11.4",
3
+ "version": "2.12.0",
4
4
  "description": "Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -45,6 +45,7 @@ import {
45
45
  DialogTitle
46
46
  } from '../ui/dialog'
47
47
  import { useSubscription } from '../../hooks/use-subscription'
48
+ import { useToast } from '../../use-toast'
48
49
 
49
50
  // Ana interface'ler ve type'lar
50
51
  export interface FileUploadProProps {
@@ -1371,6 +1372,7 @@ const FileUploadItem = ({
1371
1372
  onPauseResume?: () => void
1372
1373
  onPreview?: () => void
1373
1374
  }) => {
1375
+ const { toast } = useToast()
1374
1376
  const canPauseResume = resumable && ['uploading', 'paused'].includes(file.status)
1375
1377
  const canPreview = showPreview && file.preview && ['image', 'video', 'audio'].includes(file.preview.type)
1376
1378
 
@@ -1388,23 +1390,35 @@ const FileUploadItem = ({
1388
1390
  variant === 'grid' && "p-4"
1389
1391
  )}
1390
1392
  >
1391
- {/* Selection Checkbox */}
1392
- {allowBulkOperations && (
1393
+ {/* Selection Checkbox for grid variant only */}
1394
+ {allowBulkOperations && variant === 'grid' && (
1393
1395
  <div className="absolute top-3 left-3 z-10">
1394
1396
  <input
1395
1397
  type="checkbox"
1396
1398
  checked={selected}
1397
1399
  onChange={(e) => onSelect?.(e.target.checked)}
1398
- className="rounded border-muted-foreground/25"
1400
+ className="rounded border-muted-foreground/25 h-4 w-4"
1399
1401
  />
1400
1402
  </div>
1401
1403
  )}
1402
1404
 
1405
+ {/* Checkbox for non-grid variants */}
1406
+ {allowBulkOperations && variant !== 'grid' && (
1407
+ <input
1408
+ type="checkbox"
1409
+ checked={selected}
1410
+ onChange={(e) => onSelect?.(e.target.checked)}
1411
+ className="rounded border-muted-foreground/25 h-4 w-4 mt-1 mr-3 float-left"
1412
+ />
1413
+ )}
1414
+
1403
1415
  {/* Preview/Thumbnail */}
1404
1416
  {showPreview && file.preview && (
1405
1417
  <div className={cn(
1406
1418
  "relative overflow-hidden rounded bg-muted/20",
1407
- variant === 'grid' ? "aspect-video mb-3" : "w-12 h-12 float-left mr-3"
1419
+ variant === 'grid' ? "aspect-video mb-3" :
1420
+ variant === 'compact' ? "w-10 h-10 float-left mr-2" :
1421
+ "w-12 h-12 float-left mr-3"
1408
1422
  )}>
1409
1423
  {file.preview.type === 'image' && file.preview.thumbnail && (
1410
1424
  <img
@@ -1446,27 +1460,26 @@ const FileUploadItem = ({
1446
1460
  </div>
1447
1461
  )}
1448
1462
 
1449
- {/* File Info */}
1450
- <div className={cn(
1451
- "flex-1 min-w-0",
1452
- variant === 'grid' && "text-center",
1453
- allowBulkOperations && variant !== 'grid' && "ml-8" // Add margin when checkbox is present
1454
- )}>
1455
- <div className="flex items-start justify-between gap-2">
1456
- <div className="flex-1 min-w-0">
1457
- <h5 className={cn(
1458
- "font-medium truncate",
1459
- variant === 'compact' ? "text-sm" : "text-base"
1460
- )}>
1461
- {file.file.name}
1462
- </h5>
1463
-
1464
- {showMetadata && (
1465
- <div className={cn(
1466
- "flex items-center gap-2 mt-1 text-muted-foreground",
1467
- variant === 'compact' ? "text-xs" : "text-sm",
1468
- variant === 'grid' && "justify-center"
1463
+ {/* File Info */}
1464
+ <div className={cn(
1465
+ "flex-1 min-w-0",
1466
+ variant === 'grid' ? "text-center w-full" : "overflow-hidden"
1467
+ )}>
1468
+ <div className="flex items-start justify-between gap-3">
1469
+ <div className="min-w-0 flex-1">
1470
+ <h5 className={cn(
1471
+ "font-medium truncate",
1472
+ variant === 'compact' ? "text-sm" : "text-base"
1469
1473
  )}>
1474
+ {file.file.name}
1475
+ </h5>
1476
+
1477
+ {showMetadata && (
1478
+ <div className={cn(
1479
+ "flex items-center gap-2 mt-1 text-muted-foreground",
1480
+ variant === 'compact' ? "text-xs" : "text-sm",
1481
+ variant === 'grid' && "justify-center"
1482
+ )}>
1470
1483
  <span>{formatFileSize(file.file.size)}</span>
1471
1484
  {file.preview?.dimensions && (
1472
1485
  <>
@@ -1491,17 +1504,23 @@ const FileUploadItem = ({
1491
1504
  file.status === 'error' ? 'destructive' :
1492
1505
  file.status === 'paused' ? 'secondary' : 'secondary'
1493
1506
  }
1494
- className="flex-shrink-0"
1507
+ size={variant === 'compact' ? 'sm' : 'md'}
1508
+ className={cn(
1509
+ "flex-shrink-0 whitespace-nowrap min-w-fit",
1510
+ file.status === 'success' && "bg-green-500 hover:bg-green-600 text-white border-transparent"
1511
+ )}
1495
1512
  >
1496
- {file.status === 'uploading' && <Loader2 className="h-3 w-3 mr-1 animate-spin" />}
1497
- {file.status === 'success' && <CheckCircle2 className="h-3 w-3 mr-1" />}
1498
- {file.status === 'error' && <AlertCircle className="h-3 w-3 mr-1" />}
1499
- {file.status === 'paused' && <Pause className="h-3 w-3 mr-1" />}
1500
- {file.status === 'pending' ? 'Pending' :
1501
- file.status === 'uploading' ? 'Uploading' :
1502
- file.status === 'paused' ? 'Paused' :
1503
- file.status === 'success' ? 'Completed' :
1504
- file.status === 'error' ? 'Error' : 'Cancelled'}
1513
+ {file.status === 'uploading' && <Loader2 className={cn("h-3 w-3 animate-spin flex-shrink-0", variant !== 'compact' && "mr-1")} />}
1514
+ {file.status === 'success' && <CheckCircle2 className={cn("h-3 w-3 flex-shrink-0", variant !== 'compact' && "mr-1")} />}
1515
+ {file.status === 'error' && <AlertCircle className={cn("h-3 w-3 flex-shrink-0", variant !== 'compact' && "mr-1")} />}
1516
+ {file.status === 'paused' && <Pause className={cn("h-3 w-3 flex-shrink-0", variant !== 'compact' && "mr-1")} />}
1517
+ {variant !== 'compact' && (
1518
+ file.status === 'pending' ? 'Pending' :
1519
+ file.status === 'uploading' ? 'Uploading' :
1520
+ file.status === 'paused' ? 'Paused' :
1521
+ file.status === 'success' ? 'Done' :
1522
+ file.status === 'error' ? 'Error' : 'Cancelled'
1523
+ )}
1505
1524
  </Badge>
1506
1525
  </div>
1507
1526
 
@@ -1528,7 +1547,7 @@ const FileUploadItem = ({
1528
1547
 
1529
1548
  {/* Actions */}
1530
1549
  <div className={cn(
1531
- "flex items-center gap-1 mt-3",
1550
+ "flex items-center gap-1 mt-3 clear-both",
1532
1551
  variant === 'grid' && "justify-center"
1533
1552
  )}>
1534
1553
  {canPauseResume && (
@@ -1562,6 +1581,13 @@ const FileUploadItem = ({
1562
1581
  variant="ghost"
1563
1582
  size="sm"
1564
1583
  className="h-7 px-2"
1584
+ onClick={() => {
1585
+ // Download file
1586
+ const link = document.createElement('a')
1587
+ link.href = file.preview?.url || URL.createObjectURL(file.file)
1588
+ link.download = file.file.name
1589
+ link.click()
1590
+ }}
1565
1591
  >
1566
1592
  <Download className="h-3 w-3" />
1567
1593
  </Button>
@@ -1580,14 +1606,43 @@ const FileUploadItem = ({
1580
1606
  Preview
1581
1607
  </DropdownMenuItem>
1582
1608
  )}
1583
- <DropdownMenuItem>
1609
+ <DropdownMenuItem onClick={async () => {
1610
+ try {
1611
+ const url = file.result?.url || file.preview?.url || URL.createObjectURL(file.file)
1612
+ await navigator.clipboard.writeText(url)
1613
+ toast({
1614
+ title: "Link copied",
1615
+ description: "File link has been copied to clipboard",
1616
+ })
1617
+ } catch (err) {
1618
+ console.error('Failed to copy link:', err)
1619
+ toast({
1620
+ title: "Failed to copy",
1621
+ description: "Could not copy link to clipboard",
1622
+ variant: "destructive"
1623
+ })
1624
+ }
1625
+ }}>
1584
1626
  <Copy className="mr-2 h-4 w-4" />
1585
1627
  Copy Link
1586
1628
  </DropdownMenuItem>
1587
- <DropdownMenuItem>
1588
- <Share className="mr-2 h-4 w-4" />
1589
- Share
1590
- </DropdownMenuItem>
1629
+ {navigator.share && (
1630
+ <DropdownMenuItem onClick={async () => {
1631
+ try {
1632
+ await navigator.share({
1633
+ title: file.file.name,
1634
+ text: `Check out this file: ${file.file.name}`,
1635
+ url: file.result?.url || file.preview?.url || window.location.href,
1636
+ files: [file.file]
1637
+ })
1638
+ } catch (err) {
1639
+ console.log('Share cancelled or failed:', err)
1640
+ }
1641
+ }}>
1642
+ <Share className="mr-2 h-4 w-4" />
1643
+ Share
1644
+ </DropdownMenuItem>
1645
+ )}
1591
1646
  <DropdownMenuItem onClick={onRemove} className="text-destructive">
1592
1647
  <Trash2 className="mr-2 h-4 w-4" />
1593
1648
  Delete