@moontra/moonui-pro 2.18.1 → 2.18.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui-pro",
3
- "version": "2.18.1",
3
+ "version": "2.18.2",
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",
@@ -57,16 +57,29 @@ export function useGitHubData({
57
57
  const errorCountRef = useRef<number>(0) // Hata sayısını takip et
58
58
  const maxErrorCount = 2 // Maksimum hata sayısı
59
59
 
60
+ // checkMilestones fonksiyonunu ref olarak sakla - bu şekilde her render'da yeniden oluşturulmaz
61
+ const milestonesRef = useRef(milestones)
62
+ const onMilestoneReachedRef = useRef(onMilestoneReached)
63
+
64
+ // Ref'leri güncelle
65
+ useEffect(() => {
66
+ milestonesRef.current = milestones
67
+ }, [milestones])
68
+
69
+ useEffect(() => {
70
+ onMilestoneReachedRef.current = onMilestoneReached
71
+ }, [onMilestoneReached])
72
+
60
73
  const checkMilestones = useCallback((repos: GitHubRepository[]) => {
61
- if (!onMilestoneReached) return
74
+ if (!onMilestoneReachedRef.current) return
62
75
 
63
76
  repos.forEach(repo => {
64
77
  const previousStars = previousStarsRef.current.get(repo.full_name) || 0
65
78
  const currentStars = repo.stargazers_count
66
79
 
67
- milestones.forEach(milestone => {
80
+ milestonesRef.current.forEach(milestone => {
68
81
  if (previousStars < milestone && currentStars >= milestone) {
69
- onMilestoneReached({
82
+ onMilestoneReachedRef.current?.({
70
83
  count: milestone,
71
84
  reached: true,
72
85
  date: new Date().toISOString(),
@@ -77,7 +90,7 @@ export function useGitHubData({
77
90
 
78
91
  previousStarsRef.current.set(repo.full_name, currentStars)
79
92
  })
80
- }, [milestones, onMilestoneReached])
93
+ }, []) // Boş dependency array - fonksiyon asla yeniden oluşturulmaz
81
94
 
82
95
  const fetchData = useCallback(async () => {
83
96
  // Hata limiti aşıldıysa istek yapma
@@ -226,11 +239,11 @@ export function useGitHubData({
226
239
  }, [
227
240
  username,
228
241
  repository,
229
- repositories,
242
+ repositories?.join(','), // Array'i string'e çevir ki referans değişmesin
230
243
  token,
231
244
  sortBy,
232
245
  maxItems,
233
- checkMilestones,
246
+ checkMilestones, // Artık stable
234
247
  onDataUpdate,
235
248
  onError,
236
249
  ])
@@ -62,6 +62,27 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
62
62
  }) => {
63
63
  const { notify } = useGitHubNotifications(enableNotifications)
64
64
 
65
+ // onMilestoneReached callback'ini memoize et
66
+ const handleMilestoneReached = React.useCallback((milestone: any) => {
67
+ // Handle milestone reached
68
+ if (celebrateAt?.includes(milestone.count)) {
69
+ // Trigger celebration animation
70
+ confetti({
71
+ particleCount: 100,
72
+ spread: 70,
73
+ origin: { y: 0.6 },
74
+ })
75
+
76
+ // Show notification
77
+ notify(`🎉 Milestone Reached!`, {
78
+ body: `${milestone.count} stars achieved!`,
79
+ tag: `milestone-${milestone.count}`,
80
+ })
81
+ }
82
+
83
+ onMilestoneReached?.(milestone)
84
+ }, [celebrateAt, notify, onMilestoneReached])
85
+
65
86
  const {
66
87
  repos,
67
88
  stats,
@@ -81,29 +102,11 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
81
102
  maxItems,
82
103
  onError,
83
104
  onDataUpdate,
84
- onMilestoneReached: (milestone) => {
85
- // Handle milestone reached
86
- if (celebrateAt?.includes(milestone.count)) {
87
- // Trigger celebration animation
88
- confetti({
89
- particleCount: 100,
90
- spread: 70,
91
- origin: { y: 0.6 },
92
- })
93
-
94
- // Show notification
95
- notify(`🎉 Milestone Reached!`, {
96
- body: `${milestone.count} stars achieved!`,
97
- tag: `milestone-${milestone.count}`,
98
- })
99
- }
100
-
101
- onMilestoneReached?.(milestone)
102
- },
105
+ onMilestoneReached: handleMilestoneReached,
103
106
  milestones,
104
107
  })
105
108
 
106
- const handleExport = (format: "json" | "csv") => {
109
+ const handleExport = React.useCallback((format: "json" | "csv") => {
107
110
  if (!enableExport) return
108
111
 
109
112
  const timestamp = new Date().toISOString().split("T")[0]
@@ -116,7 +119,47 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
116
119
  } else {
117
120
  exportAsCSV(repos, `github-stars-${username}-${timestamp}.csv`)
118
121
  }
119
- }
122
+ }, [enableExport, repos, stats, username])
123
+
124
+ // handleDetailedExport fonksiyonunu memoize et
125
+ const handleDetailedExport = React.useCallback((e: React.MouseEvent) => {
126
+ if (!enableExport) return
127
+
128
+ // Show export dropdown
129
+ const dropdown = document.createElement("div")
130
+ dropdown.className = "absolute z-50 mt-2 w-48 rounded-md shadow-lg bg-popover border"
131
+ dropdown.innerHTML = `
132
+ <div class="py-1">
133
+ <button class="w-full text-left px-4 py-2 text-sm hover:bg-accent" data-format="json">
134
+ Export as JSON
135
+ </button>
136
+ <button class="w-full text-left px-4 py-2 text-sm hover:bg-accent" data-format="csv">
137
+ Export as CSV
138
+ </button>
139
+ </div>
140
+ `
141
+
142
+ dropdown.addEventListener("click", (e) => {
143
+ const target = e.target as HTMLElement
144
+ const format = target.getAttribute("data-format")
145
+ if (format === "json" || format === "csv") {
146
+ handleExport(format)
147
+ dropdown.remove()
148
+ }
149
+ })
150
+
151
+ document.body.appendChild(dropdown)
152
+
153
+ // Position dropdown
154
+ const rect = (e.target as HTMLElement).getBoundingClientRect()
155
+ dropdown.style.top = `${rect.bottom + window.scrollY}px`
156
+ dropdown.style.left = `${rect.left + window.scrollX}px`
157
+
158
+ // Remove on outside click
159
+ setTimeout(() => {
160
+ document.addEventListener("click", () => dropdown.remove(), { once: true })
161
+ }, 0)
162
+ }, [enableExport, handleExport])
120
163
 
121
164
  // Loading state
122
165
  if (loading) {
@@ -201,42 +244,7 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
201
244
  return (
202
245
  <DetailedVariant
203
246
  {...baseProps}
204
- onExport={() => {
205
- // Show export dropdown
206
- const dropdown = document.createElement("div")
207
- dropdown.className = "absolute z-50 mt-2 w-48 rounded-md shadow-lg bg-popover border"
208
- dropdown.innerHTML = `
209
- <div class="py-1">
210
- <button class="w-full text-left px-4 py-2 text-sm hover:bg-accent" data-format="json">
211
- Export as JSON
212
- </button>
213
- <button class="w-full text-left px-4 py-2 text-sm hover:bg-accent" data-format="csv">
214
- Export as CSV
215
- </button>
216
- </div>
217
- `
218
-
219
- dropdown.addEventListener("click", (e) => {
220
- const target = e.target as HTMLElement
221
- const format = target.getAttribute("data-format")
222
- if (format === "json" || format === "csv") {
223
- handleExport(format)
224
- dropdown.remove()
225
- }
226
- })
227
-
228
- document.body.appendChild(dropdown)
229
-
230
- // Position dropdown
231
- const rect = (e.target as HTMLElement).getBoundingClientRect()
232
- dropdown.style.top = `${rect.bottom + window.scrollY}px`
233
- dropdown.style.left = `${rect.left + window.scrollX}px`
234
-
235
- // Remove on outside click
236
- setTimeout(() => {
237
- document.addEventListener("click", () => dropdown.remove(), { once: true })
238
- }, 0)
239
- }}
247
+ onExport={handleDetailedExport}
240
248
  />
241
249
  )
242
250
  case "card":