@moontra/moonui 2.0.8 → 2.0.9

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.
Files changed (94) hide show
  1. package/package.json +9 -2
  2. package/src/__tests__/use-intersection-observer.test.tsx +216 -0
  3. package/src/__tests__/use-local-storage.test.tsx +174 -0
  4. package/src/__tests__/use-pro-access.test.tsx +183 -0
  5. package/src/components/ui/__tests__/accordion.test.tsx +571 -0
  6. package/src/components/ui/__tests__/alert.test.tsx +484 -0
  7. package/src/components/ui/__tests__/aspect-ratio.test.tsx +492 -0
  8. package/src/components/ui/__tests__/avatar.test.tsx +382 -0
  9. package/src/components/ui/__tests__/badge.test.tsx +364 -0
  10. package/src/components/ui/__tests__/breadcrumb.test.tsx +687 -0
  11. package/src/components/ui/__tests__/button.test.tsx +91 -0
  12. package/src/components/ui/__tests__/card.test.tsx +104 -0
  13. package/src/components/ui/__tests__/checkbox.test.tsx +591 -0
  14. package/src/components/ui/__tests__/collapsible.test.tsx +592 -0
  15. package/src/components/ui/__tests__/color-picker.test.tsx +365 -0
  16. package/src/components/ui/__tests__/command.test.tsx +677 -0
  17. package/src/components/ui/__tests__/data-table.test.tsx +256 -0
  18. package/src/components/ui/__tests__/date-picker.test.tsx +320 -0
  19. package/src/components/ui/__tests__/dialog.test.tsx +764 -0
  20. package/src/components/ui/__tests__/input.test.tsx +318 -0
  21. package/src/components/ui/__tests__/label.test.tsx +103 -0
  22. package/src/components/ui/__tests__/popover.test.tsx +637 -0
  23. package/src/components/ui/__tests__/progress.test.tsx +382 -0
  24. package/src/components/ui/__tests__/radio-group.test.tsx +555 -0
  25. package/src/components/ui/__tests__/select.test.tsx +705 -0
  26. package/src/components/ui/__tests__/skeleton.test.tsx +253 -0
  27. package/src/components/ui/__tests__/slider.test.tsx +493 -0
  28. package/src/components/ui/__tests__/switch.test.tsx +372 -0
  29. package/src/components/ui/__tests__/table.test.tsx +824 -0
  30. package/src/components/ui/__tests__/tabs.test.tsx +887 -0
  31. package/src/components/ui/__tests__/toast.test.tsx +458 -0
  32. package/src/components/ui/__tests__/tooltip.test.tsx +583 -0
  33. package/src/components/ui/accordion.tsx +63 -0
  34. package/src/components/ui/alert.tsx +130 -0
  35. package/src/components/ui/aspect-ratio.tsx +72 -0
  36. package/src/components/ui/avatar.tsx +135 -0
  37. package/src/components/ui/badge.tsx +225 -0
  38. package/src/components/ui/breadcrumb.tsx +207 -0
  39. package/src/components/ui/button.stories.tsx +162 -0
  40. package/src/components/ui/button.tsx +221 -0
  41. package/src/components/ui/calendar.tsx +262 -0
  42. package/src/components/ui/card.stories.tsx +208 -0
  43. package/src/components/ui/card.tsx +141 -0
  44. package/src/components/ui/checkbox.tsx +256 -0
  45. package/src/components/ui/collapsible.tsx +129 -0
  46. package/src/components/ui/color-picker.tsx +664 -0
  47. package/src/components/ui/command.tsx +218 -0
  48. package/src/components/ui/data-table.stories.tsx +509 -0
  49. package/src/components/ui/data-table.tsx +623 -0
  50. package/src/components/ui/date-picker.stories.tsx +321 -0
  51. package/src/components/ui/date-picker.tsx +603 -0
  52. package/src/components/ui/dialog.tsx +332 -0
  53. package/src/components/ui/dropdown-menu.tsx +200 -0
  54. package/src/components/ui/file-upload.tsx +400 -0
  55. package/src/components/ui/github-stars.tsx +201 -0
  56. package/src/components/ui/index.ts +12 -0
  57. package/src/components/ui/input.stories.tsx +255 -0
  58. package/src/components/ui/input.tsx +219 -0
  59. package/src/components/ui/label.tsx +26 -0
  60. package/src/components/ui/locked-component.tsx +215 -0
  61. package/src/components/ui/moon-logo.tsx +97 -0
  62. package/src/components/ui/pagination.tsx +116 -0
  63. package/src/components/ui/popover.tsx +183 -0
  64. package/src/components/ui/progress.tsx +182 -0
  65. package/src/components/ui/radio-group.tsx +243 -0
  66. package/src/components/ui/select.tsx +273 -0
  67. package/src/components/ui/separator.tsx +140 -0
  68. package/src/components/ui/simple-editor.tsx +652 -0
  69. package/src/components/ui/skeleton.tsx +351 -0
  70. package/src/components/ui/slider.tsx +351 -0
  71. package/src/components/ui/switch.tsx +83 -0
  72. package/src/components/ui/table.tsx +322 -0
  73. package/src/components/ui/tabs.tsx +195 -0
  74. package/src/components/ui/textarea.tsx +46 -0
  75. package/src/components/ui/toast.tsx +313 -0
  76. package/src/components/ui/toggle.tsx +47 -0
  77. package/src/components/ui/tooltip.tsx +152 -0
  78. package/src/docs/theme-system.md +1194 -0
  79. package/src/index.tsx +39 -0
  80. package/src/lib/micro-interactions.ts +255 -0
  81. package/src/lib/theme.tsx +398 -0
  82. package/src/lib/utils.ts +69 -0
  83. package/src/styles/design-system.css +365 -0
  84. package/src/styles/index.css +4 -0
  85. package/src/styles/tailwind.css +6 -0
  86. package/src/styles/tokens.css +453 -0
  87. package/src/use-intersection-observer.tsx +154 -0
  88. package/src/use-local-storage.tsx +71 -0
  89. package/src/use-paddle.ts +138 -0
  90. package/src/use-performance-optimizer.ts +379 -0
  91. package/src/use-pro-access.ts +141 -0
  92. package/src/use-scroll-animation.ts +221 -0
  93. package/src/use-subscription.ts +37 -0
  94. package/src/use-toast.ts +32 -0
@@ -0,0 +1,221 @@
1
+ 'use client'
2
+
3
+ import { useEffect, useRef, useState } from 'react'
4
+ import { useInView, useScroll, useTransform } from 'framer-motion'
5
+
6
+ interface UseScrollAnimationOptions {
7
+ threshold?: number
8
+ triggerOnce?: boolean
9
+ rootMargin?: string
10
+ }
11
+
12
+ export function useScrollAnimation(options: UseScrollAnimationOptions = {}) {
13
+ const ref = useRef<HTMLElement>(null)
14
+ const isInView = useInView(ref, {
15
+ threshold: options.threshold || 0.1,
16
+ once: options.triggerOnce ?? true,
17
+ margin: options.rootMargin || '-100px',
18
+ })
19
+
20
+ return { ref, isInView }
21
+ }
22
+
23
+ export function useScrollProgress() {
24
+ const { scrollYProgress } = useScroll()
25
+ return scrollYProgress
26
+ }
27
+
28
+ export function useScrollBasedAnimation() {
29
+ const { scrollY } = useScroll()
30
+ const y = useTransform(scrollY, [0, 300], [0, -50])
31
+ const opacity = useTransform(scrollY, [0, 300], [1, 0])
32
+ const scale = useTransform(scrollY, [0, 300], [1, 0.8])
33
+
34
+ return { y, opacity, scale, scrollY }
35
+ }
36
+
37
+ export function useParallaxScroll(speed: number = 0.5) {
38
+ const ref = useRef<HTMLElement>(null)
39
+ const { scrollYProgress } = useScroll({
40
+ target: ref,
41
+ offset: ['start end', 'end start']
42
+ })
43
+
44
+ const y = useTransform(scrollYProgress, [0, 1], [`-${speed * 100}%`, `${speed * 100}%`])
45
+
46
+ return { ref, y }
47
+ }
48
+
49
+ export function useScrollDirection() {
50
+ const [scrollDirection, setScrollDirection] = useState<'up' | 'down'>('down')
51
+ const [scrollY, setScrollY] = useState(0)
52
+
53
+ useEffect(() => {
54
+ let ticking = false
55
+
56
+ const updateScrollDirection = () => {
57
+ const newScrollY = window.scrollY
58
+
59
+ if (Math.abs(newScrollY - scrollY) < 5) {
60
+ ticking = false
61
+ return
62
+ }
63
+
64
+ setScrollDirection(newScrollY > scrollY ? 'down' : 'up')
65
+ setScrollY(newScrollY)
66
+ ticking = false
67
+ }
68
+
69
+ const handleScroll = () => {
70
+ if (!ticking) {
71
+ requestAnimationFrame(updateScrollDirection)
72
+ ticking = true
73
+ }
74
+ }
75
+
76
+ window.addEventListener('scroll', handleScroll)
77
+ return () => window.removeEventListener('scroll', handleScroll)
78
+ }, [scrollY])
79
+
80
+ return { scrollDirection, scrollY }
81
+ }
82
+
83
+ export function useScrollToElement() {
84
+ const scrollToElement = (elementId: string, offset: number = 0) => {
85
+ const element = document.getElementById(elementId)
86
+ if (element) {
87
+ const elementPosition = element.offsetTop - offset
88
+ window.scrollTo({
89
+ top: elementPosition,
90
+ behavior: 'smooth'
91
+ })
92
+ }
93
+ }
94
+
95
+ return { scrollToElement }
96
+ }
97
+
98
+ interface UseInfiniteScrollOptions {
99
+ threshold?: number
100
+ rootMargin?: string
101
+ }
102
+
103
+ export function useInfiniteScroll(
104
+ callback: () => void,
105
+ options: UseInfiniteScrollOptions = {}
106
+ ) {
107
+ const ref = useRef<HTMLElement>(null)
108
+ const isInView = useInView(ref, {
109
+ threshold: options.threshold || 0.1,
110
+ margin: options.rootMargin || '100px',
111
+ })
112
+
113
+ useEffect(() => {
114
+ if (isInView) {
115
+ callback()
116
+ }
117
+ }, [isInView, callback])
118
+
119
+ return ref
120
+ }
121
+
122
+ export function useScrollBasedScale() {
123
+ const ref = useRef<HTMLElement>(null)
124
+ const { scrollYProgress } = useScroll({
125
+ target: ref,
126
+ offset: ['start end', 'end start']
127
+ })
128
+
129
+ const scale = useTransform(scrollYProgress, [0, 0.5, 1], [0.8, 1, 0.8])
130
+ const opacity = useTransform(scrollYProgress, [0, 0.2, 0.8, 1], [0, 1, 1, 0])
131
+
132
+ return { ref, scale, opacity }
133
+ }
134
+
135
+ export function useScrollBasedRotation() {
136
+ const ref = useRef<HTMLElement>(null)
137
+ const { scrollYProgress } = useScroll({
138
+ target: ref,
139
+ offset: ['start end', 'end start']
140
+ })
141
+
142
+ const rotate = useTransform(scrollYProgress, [0, 1], [0, 360])
143
+
144
+ return { ref, rotate }
145
+ }
146
+
147
+ export function useScrollTriggeredCounter(
148
+ endValue: number,
149
+ duration: number = 2000
150
+ ) {
151
+ const [count, setCount] = useState(0)
152
+ const [isVisible, setIsVisible] = useState(false)
153
+ const ref = useRef<HTMLElement>(null)
154
+
155
+ const isInView = useInView(ref, {
156
+ threshold: 0.5,
157
+ once: true
158
+ })
159
+
160
+ useEffect(() => {
161
+ if (isInView && !isVisible) {
162
+ setIsVisible(true)
163
+ let startTime: number
164
+
165
+ const animate = (currentTime: number) => {
166
+ if (!startTime) startTime = currentTime
167
+ const elapsed = currentTime - startTime
168
+ const progress = Math.min(elapsed / duration, 1)
169
+
170
+ // Easing function for smooth animation
171
+ const easeOutQuart = 1 - Math.pow(1 - progress, 4)
172
+ setCount(Math.floor(easeOutQuart * endValue))
173
+
174
+ if (progress < 1) {
175
+ requestAnimationFrame(animate)
176
+ }
177
+ }
178
+
179
+ requestAnimationFrame(animate)
180
+ }
181
+ }, [isInView, endValue, duration, isVisible])
182
+
183
+ return { ref, count }
184
+ }
185
+
186
+ export function useScrollBasedBlur() {
187
+ const { scrollY } = useScroll()
188
+ const blur = useTransform(scrollY, [0, 300], [0, 10])
189
+
190
+ return blur
191
+ }
192
+
193
+ export function useScrollSnapPoints(snapPoints: number[]) {
194
+ const [currentSnap, setCurrentSnap] = useState(0)
195
+
196
+ useEffect(() => {
197
+ const handleScroll = () => {
198
+ const scrollPosition = window.scrollY
199
+ const closest = snapPoints.reduce((prev, curr, index) => {
200
+ return Math.abs(curr - scrollPosition) < Math.abs(snapPoints[prev] - scrollPosition)
201
+ ? index
202
+ : prev
203
+ }, 0)
204
+ setCurrentSnap(closest)
205
+ }
206
+
207
+ window.addEventListener('scroll', handleScroll)
208
+ return () => window.removeEventListener('scroll', handleScroll)
209
+ }, [snapPoints])
210
+
211
+ const scrollToSnap = (index: number) => {
212
+ if (index >= 0 && index < snapPoints.length) {
213
+ window.scrollTo({
214
+ top: snapPoints[index],
215
+ behavior: 'smooth'
216
+ })
217
+ }
218
+ }
219
+
220
+ return { currentSnap, scrollToSnap }
221
+ }
@@ -0,0 +1,37 @@
1
+ import { useSession } from "next-auth/react";
2
+
3
+ export function useSubscription() {
4
+ const { data: session, status } = useSession();
5
+
6
+ const isLoading = status === "loading";
7
+ const isAuthenticated = status === "authenticated";
8
+
9
+ // Admin kullanıcılar her zaman pro erişime sahip
10
+ const isAdmin = session?.user?.role === "admin";
11
+
12
+ // Pro abonelik kontrolü
13
+ const hasProAccess = isAdmin || session?.user?.subscription?.status === "active";
14
+ const subscriptionPlan = session?.user?.subscription?.plan || (isAdmin ? "lifetime" : "free");
15
+
16
+ // Debug bilgisi
17
+ if (process.env.NODE_ENV === 'development') {
18
+ console.log('🔍 useSubscription Debug:', {
19
+ email: session?.user?.email,
20
+ role: session?.user?.role,
21
+ isAdmin,
22
+ subscription: session?.user?.subscription,
23
+ hasProAccess,
24
+ subscriptionPlan,
25
+ status
26
+ });
27
+ }
28
+
29
+ return {
30
+ isLoading,
31
+ isAuthenticated,
32
+ isAdmin,
33
+ hasProAccess,
34
+ subscriptionPlan,
35
+ subscription: session?.user?.subscription,
36
+ };
37
+ }
@@ -0,0 +1,32 @@
1
+ // Toast hook - şimdilik basit bir implementasyon
2
+ // Gerçek implementasyonda Toaster component'i ile entegre olacak
3
+
4
+ interface ToastOptions {
5
+ title: string;
6
+ description?: string;
7
+ variant?: 'default' | 'destructive';
8
+ }
9
+
10
+ export function toast(options: ToastOptions) {
11
+ // Şimdilik console'a yazdıralım
12
+ // Gerçek implementasyonda toast notification gösterilecek
13
+ console.log('Toast:', options);
14
+
15
+ // Browser'da alert gösterelim (geçici çözüm)
16
+ if (typeof window !== 'undefined') {
17
+ const message = options.description
18
+ ? `${options.title}\n\n${options.description}`
19
+ : options.title;
20
+
21
+ // Variant'a göre stil belirle
22
+ if (options.variant === 'destructive') {
23
+ console.error(message);
24
+ } else {
25
+ console.log(message);
26
+ }
27
+ }
28
+ }
29
+
30
+ export const useToast = () => {
31
+ return { toast };
32
+ };