@moontra/moonui-pro 2.5.5 → 2.5.7
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 +1 -0
- package/dist/index.mjs +38 -24
- package/package.json +1 -1
- package/src/components/sidebar/index.tsx +46 -34
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { twMerge } from 'tailwind-merge';
|
|
|
3
3
|
import * as t from 'react';
|
|
4
4
|
import t__default, { useState, useRef, useCallback, forwardRef, createContext, useContext, useMemo, useEffect, useDebugValue, Component, useLayoutEffect } from 'react';
|
|
5
5
|
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
6
|
-
import { ChevronDown, Info, AlertCircle, AlertTriangle, Check, X, MoreHorizontal, Loader2, Minus, Search, ChevronRight, Circle, ChevronUp, Lock, Sparkles, Plus, ChevronLeft, Calendar as Calendar$1, Edit, Trash2, Clock, MapPin, User, GripVertical, MessageCircle, Paperclip, Bold as Bold$1, Italic as Italic$1, Underline as Underline$1, Strikethrough, Code as Code$1, Type, Heading1, Heading2, Heading3, AlignLeft, AlignCenter, AlignRight, AlignJustify, List, ListOrdered, CheckSquare, Quote, Palette, Highlighter, Link2, Image as Image$1, Table as Table$1, Settings, Undo, Redo, Eye, RefreshCw, Wand2, Maximize, FileText, Languages, TrendingUp, TrendingDown, ZoomOut, ZoomIn, Download, FileSpreadsheet, FileJson, Maximize2, Move, Menu, Bell, Edit3, LayoutGrid, Upload, Share2, Save, CheckCircle2, Filter, FileDown, ArrowUp, ArrowDown, ArrowUpDown, ChevronsLeft, ChevronsRight, ExternalLink, CalendarIcon, DollarSign, Users, Github, Star, GitFork, Activity, Server, EyeOff, RotateCw, Zap,
|
|
6
|
+
import { ChevronDown, Info, AlertCircle, AlertTriangle, Check, X, MoreHorizontal, Loader2, Minus, Search, ChevronRight, Circle, ChevronUp, Lock, Sparkles, Plus, ChevronLeft, Calendar as Calendar$1, Edit, Trash2, Clock, MapPin, User, GripVertical, MessageCircle, Paperclip, Bold as Bold$1, Italic as Italic$1, Underline as Underline$1, Strikethrough, Code as Code$1, Type, Heading1, Heading2, Heading3, AlignLeft, AlignCenter, AlignRight, AlignJustify, List, ListOrdered, CheckSquare, Quote, Palette, Highlighter, Link2, Image as Image$1, Table as Table$1, Settings, Undo, Redo, Eye, RefreshCw, Wand2, Maximize, FileText, Languages, TrendingUp, TrendingDown, ZoomOut, ZoomIn, Download, FileSpreadsheet, FileJson, Maximize2, Move, Menu, Bell, Edit3, LayoutGrid, Upload, Share2, Save, CheckCircle2, Filter, FileDown, ArrowUp, ArrowDown, ArrowUpDown, ChevronsLeft, ChevronsRight, Pin, Sun, Moon, Monitor, ExternalLink, CalendarIcon, DollarSign, Users, Github, Star, GitFork, Activity, Server, EyeOff, RotateCw, Zap, Timer, Cpu, MemoryStick, HardDrive, Network, CheckCircle, BarChart3, Video, Music, Archive, File, Columns, XCircle, Grip, Unlock, Minimize2, Map as Map$1, Target, MoreVertical, BellOff, ArrowDownRight, ArrowUpRight } from 'lucide-react';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { cva } from 'class-variance-authority';
|
|
9
9
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
@@ -56410,12 +56410,17 @@ function Sidebar({
|
|
|
56410
56410
|
document.addEventListener("mousemove", handleMouseMove2);
|
|
56411
56411
|
return () => document.removeEventListener("mousemove", handleMouseMove2);
|
|
56412
56412
|
}, [animatedBackground, mouseX, mouseY]);
|
|
56413
|
-
const toggleSection = (sectionId) => {
|
|
56413
|
+
const toggleSection = useCallback((sectionId) => {
|
|
56414
56414
|
setExpandedSections(
|
|
56415
56415
|
(prev) => prev.includes(sectionId) ? prev.filter((id) => id !== sectionId) : [...prev, sectionId]
|
|
56416
56416
|
);
|
|
56417
|
-
};
|
|
56418
|
-
|
|
56417
|
+
}, []);
|
|
56418
|
+
useCallback((itemId) => {
|
|
56419
|
+
setPinnedItems(
|
|
56420
|
+
(prev) => prev.includes(itemId) ? prev.filter((id) => id !== itemId) : [...prev, itemId]
|
|
56421
|
+
);
|
|
56422
|
+
}, []);
|
|
56423
|
+
const handleItemClick = useCallback((item) => {
|
|
56419
56424
|
if (item.action) {
|
|
56420
56425
|
item.action();
|
|
56421
56426
|
} else if (item.href && onNavigate) {
|
|
@@ -56424,8 +56429,8 @@ function Sidebar({
|
|
|
56424
56429
|
setIsOpen(false);
|
|
56425
56430
|
}
|
|
56426
56431
|
}
|
|
56427
|
-
};
|
|
56428
|
-
const filterItems = (items, query) => {
|
|
56432
|
+
}, [onNavigate, isMobile]);
|
|
56433
|
+
const filterItems = useCallback((items, query) => {
|
|
56429
56434
|
if (!query)
|
|
56430
56435
|
return items;
|
|
56431
56436
|
return items.filter((item) => {
|
|
@@ -56435,8 +56440,17 @@ function Sidebar({
|
|
|
56435
56440
|
);
|
|
56436
56441
|
return matchesTitle || hasMatchingChildren;
|
|
56437
56442
|
});
|
|
56438
|
-
};
|
|
56439
|
-
const
|
|
56443
|
+
}, []);
|
|
56444
|
+
const filteredSections = useMemo(() => {
|
|
56445
|
+
return sections.map((section) => ({
|
|
56446
|
+
...section,
|
|
56447
|
+
filteredItems: filterItems(section.items, searchQuery).map((item) => ({
|
|
56448
|
+
...item,
|
|
56449
|
+
filteredChildren: item.items ? filterItems(item.items, searchQuery) : void 0
|
|
56450
|
+
}))
|
|
56451
|
+
})).filter((section) => section.filteredItems.length > 0);
|
|
56452
|
+
}, [sections, searchQuery, filterItems]);
|
|
56453
|
+
const renderItem = useCallback((item, depth = 0, filteredChildren) => {
|
|
56440
56454
|
const isActive2 = item.href === activePath;
|
|
56441
56455
|
const isPinned = pinnedItems.includes(item.id);
|
|
56442
56456
|
const hasChildren = item.items && item.items.length > 0;
|
|
@@ -56496,7 +56510,7 @@ function Sidebar({
|
|
|
56496
56510
|
/* @__PURE__ */ jsx(ItemWrapper, { children: itemContent }),
|
|
56497
56511
|
/* @__PURE__ */ jsx(MoonUITooltipContentPro, { side: "right", children: /* @__PURE__ */ jsx("p", { children: item.tooltip }) })
|
|
56498
56512
|
] }) }) : itemContent,
|
|
56499
|
-
hasChildren && !collapsed && /* @__PURE__ */ jsx(AnimatePresence, { children: isExpanded && /* @__PURE__ */ jsx(
|
|
56513
|
+
hasChildren && !collapsed && filteredChildren && /* @__PURE__ */ jsx(AnimatePresence, { children: isExpanded && /* @__PURE__ */ jsx(
|
|
56500
56514
|
motion.div,
|
|
56501
56515
|
{
|
|
56502
56516
|
initial: { height: 0, opacity: 0 },
|
|
@@ -56504,14 +56518,14 @@ function Sidebar({
|
|
|
56504
56518
|
exit: { height: 0, opacity: 0 },
|
|
56505
56519
|
transition: { duration: 0.2 },
|
|
56506
56520
|
className: "overflow-hidden",
|
|
56507
|
-
children: /* @__PURE__ */ jsx("div", { className: "pt-1 space-y-1", children:
|
|
56521
|
+
children: /* @__PURE__ */ jsx("div", { className: "pt-1 space-y-1", children: filteredChildren.map(
|
|
56508
56522
|
(child) => renderItem(child, depth + 1)
|
|
56509
56523
|
) })
|
|
56510
56524
|
}
|
|
56511
56525
|
) })
|
|
56512
56526
|
] }, item.id);
|
|
56513
|
-
};
|
|
56514
|
-
const SidebarContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
56527
|
+
}, [activePath, pinnedItems, expandedSections, collapsed, customStyles, handleItemClick, toggleSection]);
|
|
56528
|
+
const SidebarContent = t__default.memo(() => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
56515
56529
|
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
56516
56530
|
"flex items-center gap-3 p-4 border-b",
|
|
56517
56531
|
collapsed && !isMobile && "justify-center px-2"
|
|
@@ -56557,8 +56571,13 @@ function Sidebar({
|
|
|
56557
56571
|
setSearchQuery(e.target.value);
|
|
56558
56572
|
onSearchChange?.(e.target.value);
|
|
56559
56573
|
},
|
|
56574
|
+
autoComplete: "off",
|
|
56575
|
+
autoCorrect: "off",
|
|
56576
|
+
autoCapitalize: "off",
|
|
56577
|
+
spellCheck: "false",
|
|
56560
56578
|
className: "pl-9 pr-9"
|
|
56561
|
-
}
|
|
56579
|
+
},
|
|
56580
|
+
"sidebar-search-input"
|
|
56562
56581
|
),
|
|
56563
56582
|
keyboardShortcuts && /* @__PURE__ */ jsxs("kbd", { className: "absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 hidden sm:flex", children: [
|
|
56564
56583
|
/* @__PURE__ */ jsx("span", { className: "text-xs", children: "\u2318" }),
|
|
@@ -56571,16 +56590,11 @@ function Sidebar({
|
|
|
56571
56590
|
(section) => section.items.filter((item) => pinnedItems.includes(item.id))
|
|
56572
56591
|
).map((item) => renderItem(item)) })
|
|
56573
56592
|
] }),
|
|
56574
|
-
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx("div", { className: "p-4 space-y-6", children:
|
|
56575
|
-
|
|
56576
|
-
|
|
56577
|
-
|
|
56578
|
-
|
|
56579
|
-
section.title && (!collapsed || isMobile) && /* @__PURE__ */ jsx("h4", { className: "text-xs font-medium text-muted-foreground mb-2", children: section.title }),
|
|
56580
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: filteredItems.map((item) => renderItem(item)) }),
|
|
56581
|
-
section.showDivider && index < sections.length - 1 && /* @__PURE__ */ jsx(MoonUISeparatorPro, { className: "mt-4" })
|
|
56582
|
-
] }, section.id);
|
|
56583
|
-
}) }) }),
|
|
56593
|
+
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx("div", { className: "p-4 space-y-6", children: filteredSections.map((section, index) => /* @__PURE__ */ jsxs("div", { children: [
|
|
56594
|
+
section.title && (!collapsed || isMobile) && /* @__PURE__ */ jsx("h4", { className: "text-xs font-medium text-muted-foreground mb-2", children: section.title }),
|
|
56595
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: section.filteredItems.map((item) => renderItem(item, 0, item.filteredChildren)) }),
|
|
56596
|
+
section.showDivider && index < filteredSections.length - 1 && /* @__PURE__ */ jsx(MoonUISeparatorPro, { className: "mt-4" })
|
|
56597
|
+
] }, section.id)) }) }),
|
|
56584
56598
|
footer && /* @__PURE__ */ jsxs("div", { className: "border-t p-4", children: [
|
|
56585
56599
|
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: footer.items.map((item) => renderItem(item)) }),
|
|
56586
56600
|
showThemeToggle && (!collapsed || isMobile) && /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-between", children: [
|
|
@@ -56608,7 +56622,7 @@ function Sidebar({
|
|
|
56608
56622
|
] })
|
|
56609
56623
|
] })
|
|
56610
56624
|
] })
|
|
56611
|
-
] });
|
|
56625
|
+
] }));
|
|
56612
56626
|
const sidebarClasses = cn(
|
|
56613
56627
|
"flex h-full flex-col bg-background border-r",
|
|
56614
56628
|
glassmorphism && "bg-background/80 backdrop-blur-xl border-white/10",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moontra/moonui-pro",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.7",
|
|
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",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import React, { useState, useEffect, useCallback, useRef } from 'react'
|
|
3
|
+
import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react'
|
|
4
4
|
import { motion, AnimatePresence, useMotionValue, useSpring } from 'framer-motion'
|
|
5
5
|
import { cn } from '../../lib/utils'
|
|
6
6
|
import { Button } from '../ui/button'
|
|
@@ -48,6 +48,7 @@ export interface SidebarItem {
|
|
|
48
48
|
items?: SidebarItem[]
|
|
49
49
|
action?: () => void
|
|
50
50
|
tooltip?: string
|
|
51
|
+
filteredChildren?: SidebarItem[]
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
export interface SidebarSection {
|
|
@@ -230,23 +231,23 @@ export function Sidebar({
|
|
|
230
231
|
return () => document.removeEventListener('mousemove', handleMouseMove)
|
|
231
232
|
}, [animatedBackground, mouseX, mouseY])
|
|
232
233
|
|
|
233
|
-
const toggleSection = (sectionId: string) => {
|
|
234
|
+
const toggleSection = useCallback((sectionId: string) => {
|
|
234
235
|
setExpandedSections(prev =>
|
|
235
236
|
prev.includes(sectionId)
|
|
236
237
|
? prev.filter(id => id !== sectionId)
|
|
237
238
|
: [...prev, sectionId]
|
|
238
239
|
)
|
|
239
|
-
}
|
|
240
|
+
}, [])
|
|
240
241
|
|
|
241
|
-
const togglePinItem = (itemId: string) => {
|
|
242
|
+
const togglePinItem = useCallback((itemId: string) => {
|
|
242
243
|
setPinnedItems(prev =>
|
|
243
244
|
prev.includes(itemId)
|
|
244
245
|
? prev.filter(id => id !== itemId)
|
|
245
246
|
: [...prev, itemId]
|
|
246
247
|
)
|
|
247
|
-
}
|
|
248
|
+
}, [])
|
|
248
249
|
|
|
249
|
-
const handleItemClick = (item: SidebarItem) => {
|
|
250
|
+
const handleItemClick = useCallback((item: SidebarItem) => {
|
|
250
251
|
if (item.action) {
|
|
251
252
|
item.action()
|
|
252
253
|
} else if (item.href && onNavigate) {
|
|
@@ -255,9 +256,9 @@ export function Sidebar({
|
|
|
255
256
|
setIsOpen(false)
|
|
256
257
|
}
|
|
257
258
|
}
|
|
258
|
-
}
|
|
259
|
+
}, [onNavigate, isMobile])
|
|
259
260
|
|
|
260
|
-
const filterItems = (items: SidebarItem[], query: string): SidebarItem[] => {
|
|
261
|
+
const filterItems = useCallback((items: SidebarItem[], query: string): SidebarItem[] => {
|
|
261
262
|
if (!query) return items
|
|
262
263
|
|
|
263
264
|
return items.filter(item => {
|
|
@@ -267,9 +268,20 @@ export function Sidebar({
|
|
|
267
268
|
)
|
|
268
269
|
return matchesTitle || hasMatchingChildren
|
|
269
270
|
})
|
|
270
|
-
}
|
|
271
|
+
}, [])
|
|
271
272
|
|
|
272
|
-
|
|
273
|
+
// Filtered sections memoized to prevent re-renders
|
|
274
|
+
const filteredSections = useMemo(() => {
|
|
275
|
+
return sections.map(section => ({
|
|
276
|
+
...section,
|
|
277
|
+
filteredItems: filterItems(section.items, searchQuery).map(item => ({
|
|
278
|
+
...item,
|
|
279
|
+
filteredChildren: item.items ? filterItems(item.items, searchQuery) : undefined
|
|
280
|
+
}))
|
|
281
|
+
})).filter(section => section.filteredItems.length > 0)
|
|
282
|
+
}, [sections, searchQuery, filterItems])
|
|
283
|
+
|
|
284
|
+
const renderItem = useCallback((item: SidebarItem, depth = 0, filteredChildren?: SidebarItem[]) => {
|
|
273
285
|
const isActive = item.href === activePath
|
|
274
286
|
const isPinned = pinnedItems.includes(item.id)
|
|
275
287
|
const hasChildren = item.items && item.items.length > 0
|
|
@@ -353,7 +365,7 @@ export function Sidebar({
|
|
|
353
365
|
itemContent
|
|
354
366
|
)}
|
|
355
367
|
|
|
356
|
-
{hasChildren && !collapsed && (
|
|
368
|
+
{hasChildren && !collapsed && filteredChildren && (
|
|
357
369
|
<AnimatePresence>
|
|
358
370
|
{isExpanded && (
|
|
359
371
|
<motion.div
|
|
@@ -364,7 +376,7 @@ export function Sidebar({
|
|
|
364
376
|
className="overflow-hidden"
|
|
365
377
|
>
|
|
366
378
|
<div className="pt-1 space-y-1">
|
|
367
|
-
{
|
|
379
|
+
{filteredChildren.map(child =>
|
|
368
380
|
renderItem(child, depth + 1)
|
|
369
381
|
)}
|
|
370
382
|
</div>
|
|
@@ -374,9 +386,9 @@ export function Sidebar({
|
|
|
374
386
|
)}
|
|
375
387
|
</div>
|
|
376
388
|
)
|
|
377
|
-
}
|
|
389
|
+
}, [activePath, pinnedItems, expandedSections, collapsed, customStyles, handleItemClick, toggleSection])
|
|
378
390
|
|
|
379
|
-
const SidebarContent = () => (
|
|
391
|
+
const SidebarContent = React.memo(() => (
|
|
380
392
|
<>
|
|
381
393
|
{/* Header */}
|
|
382
394
|
<div className={cn(
|
|
@@ -424,6 +436,7 @@ export function Sidebar({
|
|
|
424
436
|
<div className="relative">
|
|
425
437
|
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
|
426
438
|
<Input
|
|
439
|
+
key="sidebar-search-input"
|
|
427
440
|
ref={searchInputRef}
|
|
428
441
|
type="search"
|
|
429
442
|
placeholder={searchPlaceholder}
|
|
@@ -432,6 +445,10 @@ export function Sidebar({
|
|
|
432
445
|
setSearchQuery(e.target.value)
|
|
433
446
|
onSearchChange?.(e.target.value)
|
|
434
447
|
}}
|
|
448
|
+
autoComplete="off"
|
|
449
|
+
autoCorrect="off"
|
|
450
|
+
autoCapitalize="off"
|
|
451
|
+
spellCheck="false"
|
|
435
452
|
className="pl-9 pr-9"
|
|
436
453
|
/>
|
|
437
454
|
{keyboardShortcuts && (
|
|
@@ -458,26 +475,21 @@ export function Sidebar({
|
|
|
458
475
|
{/* Main Content */}
|
|
459
476
|
<ScrollArea className="flex-1 overflow-y-auto">
|
|
460
477
|
<div className="p-4 space-y-6">
|
|
461
|
-
{
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
</h4>
|
|
471
|
-
)}
|
|
472
|
-
<div className="space-y-1">
|
|
473
|
-
{filteredItems.map(item => renderItem(item))}
|
|
474
|
-
</div>
|
|
475
|
-
{section.showDivider && index < sections.length - 1 && (
|
|
476
|
-
<Separator className="mt-4" />
|
|
477
|
-
)}
|
|
478
|
+
{filteredSections.map((section, index) => (
|
|
479
|
+
<div key={section.id}>
|
|
480
|
+
{section.title && (!collapsed || isMobile) && (
|
|
481
|
+
<h4 className="text-xs font-medium text-muted-foreground mb-2">
|
|
482
|
+
{section.title}
|
|
483
|
+
</h4>
|
|
484
|
+
)}
|
|
485
|
+
<div className="space-y-1">
|
|
486
|
+
{section.filteredItems.map(item => renderItem(item, 0, item.filteredChildren))}
|
|
478
487
|
</div>
|
|
479
|
-
|
|
480
|
-
|
|
488
|
+
{section.showDivider && index < filteredSections.length - 1 && (
|
|
489
|
+
<Separator className="mt-4" />
|
|
490
|
+
)}
|
|
491
|
+
</div>
|
|
492
|
+
))}
|
|
481
493
|
</div>
|
|
482
494
|
</ScrollArea>
|
|
483
495
|
|
|
@@ -519,7 +531,7 @@ export function Sidebar({
|
|
|
519
531
|
</div>
|
|
520
532
|
)}
|
|
521
533
|
</>
|
|
522
|
-
)
|
|
534
|
+
))
|
|
523
535
|
|
|
524
536
|
const sidebarClasses = cn(
|
|
525
537
|
"flex h-full flex-col bg-background border-r",
|