@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 CHANGED
@@ -1821,6 +1821,7 @@ interface SidebarItem {
1821
1821
  items?: SidebarItem[];
1822
1822
  action?: () => void;
1823
1823
  tooltip?: string;
1824
+ filteredChildren?: SidebarItem[];
1824
1825
  }
1825
1826
  interface SidebarSection {
1826
1827
  id: string;
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, Monitor, Timer, Cpu, MemoryStick, HardDrive, Network, CheckCircle, BarChart3, Video, Music, Archive, File, Columns, Sun, Moon, XCircle, Grip, Unlock, Minimize2, Map as Map$1, Target, Pin, MoreVertical, BellOff, ArrowDownRight, ArrowUpRight } from 'lucide-react';
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
- const handleItemClick = (item) => {
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 renderItem = (item, depth = 0) => {
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: filterItems(item.items, searchQuery).map(
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: sections.map((section, index) => {
56575
- const filteredItems = filterItems(section.items, searchQuery);
56576
- if (filteredItems.length === 0)
56577
- return null;
56578
- return /* @__PURE__ */ jsxs("div", { children: [
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.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
- const renderItem = (item: SidebarItem, depth = 0) => {
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
- {filterItems(item.items!, searchQuery).map(child =>
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
- {sections.map((section, index) => {
462
- const filteredItems = filterItems(section.items, searchQuery)
463
- if (filteredItems.length === 0) return null
464
-
465
- return (
466
- <div key={section.id}>
467
- {section.title && (!collapsed || isMobile) && (
468
- <h4 className="text-xs font-medium text-muted-foreground mb-2">
469
- {section.title}
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",