@moontra/moonui-pro 2.5.11 → 2.5.12

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.mjs CHANGED
@@ -56306,27 +56306,44 @@ var TableRow2 = t__default.memo(({
56306
56306
  return prevRowId === nextRowId && prevProps.isExpanded === nextProps.isExpanded && prevProps.row.getIsSelected() === nextProps.row.getIsSelected() && prevVisibilityKeys === nextVisibilityKeys && prevVisibilityValues === nextVisibilityValues;
56307
56307
  });
56308
56308
  TableRow2.displayName = "TableRow";
56309
- var SearchInput = t__default.forwardRef(({ placeholder, defaultValue, onChange, keyboardShortcuts }, ref) => {
56310
- const localRef = useRef(null);
56311
- const inputRef = ref || localRef;
56312
- const handleChange = useCallback((e) => {
56313
- onChange(e.target.value);
56314
- }, [onChange]);
56309
+ var SearchInput = t__default.memo(({
56310
+ searchInputRef,
56311
+ searchPlaceholder,
56312
+ initialValue,
56313
+ onSearchChange,
56314
+ keyboardShortcuts
56315
+ }) => {
56316
+ const [localValue, setLocalValue] = useState(initialValue || "");
56317
+ const timeoutRef = useRef();
56315
56318
  useEffect(() => {
56316
- const input = typeof inputRef === "object" && inputRef?.current;
56317
- if (input && input.value !== defaultValue) {
56318
- input.value = defaultValue;
56319
+ setLocalValue(initialValue);
56320
+ }, [initialValue]);
56321
+ const handleChange = useCallback((e) => {
56322
+ const newValue = e.target.value;
56323
+ setLocalValue(newValue);
56324
+ if (timeoutRef.current) {
56325
+ clearTimeout(timeoutRef.current);
56319
56326
  }
56320
- }, [defaultValue, inputRef]);
56327
+ timeoutRef.current = setTimeout(() => {
56328
+ onSearchChange(newValue);
56329
+ }, 300);
56330
+ }, [onSearchChange]);
56331
+ useEffect(() => {
56332
+ return () => {
56333
+ if (timeoutRef.current) {
56334
+ clearTimeout(timeoutRef.current);
56335
+ }
56336
+ };
56337
+ }, []);
56321
56338
  return /* @__PURE__ */ jsx("div", { className: "p-4 border-b", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
56322
56339
  /* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" }),
56323
56340
  /* @__PURE__ */ jsx(
56324
56341
  "input",
56325
56342
  {
56326
- ref: inputRef,
56343
+ ref: searchInputRef,
56327
56344
  type: "text",
56328
- placeholder,
56329
- defaultValue,
56345
+ placeholder: searchPlaceholder,
56346
+ value: localValue,
56330
56347
  onChange: handleChange,
56331
56348
  autoComplete: "off",
56332
56349
  autoCorrect: "off",
@@ -56341,7 +56358,6 @@ var SearchInput = t__default.forwardRef(({ placeholder, defaultValue, onChange,
56341
56358
  ] })
56342
56359
  ] }) });
56343
56360
  });
56344
- SearchInput.displayName = "SearchInput";
56345
56361
  function Sidebar({
56346
56362
  sections,
56347
56363
  footer,
@@ -56611,20 +56627,6 @@ function Sidebar({
56611
56627
  )
56612
56628
  ] });
56613
56629
  });
56614
- const searchComponent = useMemo(() => {
56615
- if (!showSearch)
56616
- return null;
56617
- return /* @__PURE__ */ jsx(
56618
- SearchInput,
56619
- {
56620
- ref: searchInputRef,
56621
- placeholder: searchPlaceholder,
56622
- defaultValue: searchQuery,
56623
- onChange: handleSearch,
56624
- keyboardShortcuts
56625
- }
56626
- );
56627
- }, [showSearch, searchPlaceholder, keyboardShortcuts, handleSearch]);
56628
56630
  const SidebarMenuContent = t__default.memo(() => {
56629
56631
  return /* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-6", children: [
56630
56632
  pinnedItems.length > 0 && (!collapsed || isMobile) && /* @__PURE__ */ jsxs("div", { children: [
@@ -56673,7 +56675,16 @@ function Sidebar({
56673
56675
  const SidebarContent = t__default.memo(() => {
56674
56676
  return /* @__PURE__ */ jsxs(Fragment, { children: [
56675
56677
  /* @__PURE__ */ jsx(SidebarHeader, {}),
56676
- showSearch && (!collapsed || isMobile) && searchComponent,
56678
+ showSearch && (!collapsed || isMobile) && /* @__PURE__ */ jsx(
56679
+ SearchInput,
56680
+ {
56681
+ searchInputRef,
56682
+ searchPlaceholder,
56683
+ initialValue: searchQuery,
56684
+ onSearchChange: handleSearch,
56685
+ keyboardShortcuts
56686
+ }
56687
+ ),
56677
56688
  /* @__PURE__ */ jsx(SidebarMenuContent, {}),
56678
56689
  /* @__PURE__ */ jsx(SidebarFooter, {})
56679
56690
  ] });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui-pro",
3
- "version": "2.5.11",
3
+ "version": "2.5.12",
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",
@@ -36,41 +36,63 @@ import {
36
36
  DropdownMenuTrigger,
37
37
  } from '../ui/dropdown-menu'
38
38
 
39
- // Uncontrolled Search Input to preserve focus
40
- const SearchInput = React.forwardRef<
41
- HTMLInputElement,
42
- {
43
- placeholder: string
44
- defaultValue: string
45
- onChange: (value: string) => void
46
- keyboardShortcuts: boolean
47
- }
48
- >(({ placeholder, defaultValue, onChange, keyboardShortcuts }, ref) => {
49
- const localRef = useRef<HTMLInputElement>(null)
50
- const inputRef = ref || localRef
39
+ // Search Input Component - with local state to prevent focus loss
40
+ const SearchInput = React.memo(({
41
+ searchInputRef,
42
+ searchPlaceholder,
43
+ initialValue,
44
+ onSearchChange,
45
+ keyboardShortcuts
46
+ }: {
47
+ searchInputRef: React.RefObject<HTMLInputElement | null>
48
+ searchPlaceholder: string
49
+ initialValue: string
50
+ onSearchChange: (value: string) => void
51
+ keyboardShortcuts: boolean
52
+ }) => {
53
+ // Local state to prevent focus loss
54
+ const [localValue, setLocalValue] = useState<string>(initialValue || '')
55
+ const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>()
56
+
57
+ // Update local value when initial value changes from parent
58
+ useEffect(() => {
59
+ setLocalValue(initialValue)
60
+ }, [initialValue])
51
61
 
52
- // Use uncontrolled input with onChange
62
+ // Handle input changes locally and debounce to parent
53
63
  const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
54
- onChange(e.target.value)
55
- }, [onChange])
64
+ const newValue = e.target.value
65
+ setLocalValue(newValue)
66
+
67
+ // Clear previous timeout
68
+ if (timeoutRef.current) {
69
+ clearTimeout(timeoutRef.current)
70
+ }
71
+
72
+ // Debounce the parent update
73
+ timeoutRef.current = setTimeout(() => {
74
+ onSearchChange(newValue)
75
+ }, 300)
76
+ }, [onSearchChange])
56
77
 
57
- // Update value programmatically when defaultValue changes
78
+ // Cleanup timeout on unmount
58
79
  useEffect(() => {
59
- const input = typeof inputRef === 'object' && inputRef?.current
60
- if (input && input.value !== defaultValue) {
61
- input.value = defaultValue
80
+ return () => {
81
+ if (timeoutRef.current) {
82
+ clearTimeout(timeoutRef.current)
83
+ }
62
84
  }
63
- }, [defaultValue, inputRef])
85
+ }, [])
64
86
 
65
87
  return (
66
88
  <div className="p-4 border-b">
67
89
  <div className="relative">
68
90
  <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
69
91
  <input
70
- ref={inputRef as React.RefObject<HTMLInputElement>}
92
+ ref={searchInputRef}
71
93
  type="text"
72
- placeholder={placeholder}
73
- defaultValue={defaultValue}
94
+ placeholder={searchPlaceholder}
95
+ value={localValue}
74
96
  onChange={handleChange}
75
97
  autoComplete="off"
76
98
  autoCorrect="off"
@@ -87,7 +109,6 @@ const SearchInput = React.forwardRef<
87
109
  </div>
88
110
  )
89
111
  })
90
- SearchInput.displayName = 'SearchInput'
91
112
 
92
113
  export interface SidebarItem {
93
114
  id: string
@@ -190,7 +211,7 @@ export function Sidebar({
190
211
  const [expandedSections, setExpandedSections] = useState<string[]>([])
191
212
  const [currentSearchQuery, setCurrentSearchQuery] = useState(searchQuery)
192
213
  const [pinnedItems, setPinnedItems] = useState<string[]>([])
193
- const searchInputRef = useRef<HTMLInputElement>(null)
214
+ const searchInputRef = useRef<HTMLInputElement | null>(null)
194
215
  const mouseX = useMotionValue(0)
195
216
  const mouseY = useMotionValue(0)
196
217
  const springX = useSpring(mouseX, { stiffness: 300, damping: 30 })
@@ -508,19 +529,6 @@ export function Sidebar({
508
529
  )
509
530
  })
510
531
 
511
- // Create stable search component with uncontrolled input
512
- const searchComponent = useMemo(() => {
513
- if (!showSearch) return null
514
- return (
515
- <SearchInput
516
- ref={searchInputRef}
517
- placeholder={searchPlaceholder}
518
- defaultValue={searchQuery}
519
- onChange={handleSearch}
520
- keyboardShortcuts={keyboardShortcuts}
521
- />
522
- )
523
- }, [showSearch, searchPlaceholder, keyboardShortcuts, handleSearch]) // Only re-create when these stable props change
524
532
 
525
533
  // Menu Content
526
534
  const SidebarMenuContent = React.memo(() => {
@@ -605,7 +613,15 @@ export function Sidebar({
605
613
  return (
606
614
  <>
607
615
  <SidebarHeader />
608
- {showSearch && (!collapsed || isMobile) && searchComponent}
616
+ {showSearch && (!collapsed || isMobile) && (
617
+ <SearchInput
618
+ searchInputRef={searchInputRef}
619
+ searchPlaceholder={searchPlaceholder}
620
+ initialValue={searchQuery}
621
+ onSearchChange={handleSearch}
622
+ keyboardShortcuts={keyboardShortcuts}
623
+ />
624
+ )}
609
625
  <SidebarMenuContent />
610
626
  <SidebarFooter />
611
627
  </>