create-unmint 1.0.0 → 1.1.0

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.js CHANGED
@@ -312,15 +312,19 @@ async function init(projectName, options = {}) {
312
312
  gitSpinner.warn("Could not initialize git repository");
313
313
  }
314
314
  }
315
+ let depsInstalled = false;
315
316
  if (config.installDeps) {
316
317
  const installSpinner = ora("Installing dependencies...").start();
317
318
  try {
318
319
  const packageManager = await detectPackageManager();
319
- await execa(packageManager, ["install"], { cwd: targetDir });
320
+ await execa(packageManager, ["install"], { cwd: targetDir, stdio: "pipe" });
320
321
  installSpinner.succeed(`Dependencies installed with ${packageManager}`);
322
+ depsInstalled = true;
321
323
  } catch (error) {
322
324
  installSpinner.warn("Could not install dependencies");
323
- console.log(chalk2.dim(` Run "npm install" manually to install dependencies`));
325
+ if (error instanceof Error && "stderr" in error) {
326
+ console.log(chalk2.dim(` ${error.stderr?.slice(0, 200) || error.message}`));
327
+ }
324
328
  }
325
329
  }
326
330
  console.log();
@@ -329,7 +333,7 @@ async function init(projectName, options = {}) {
329
333
  console.log(" Next steps:");
330
334
  console.log();
331
335
  console.log(chalk2.cyan(` cd ${config.projectName}`));
332
- if (!config.installDeps) {
336
+ if (!depsInstalled) {
333
337
  console.log(chalk2.cyan(" npm install"));
334
338
  }
335
339
  console.log(chalk2.cyan(" npm run dev"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-unmint",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Create a new Unmint documentation project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,90 @@
1
+ 'use client'
2
+
3
+ import { useState, useCallback } from 'react'
4
+ import Link from 'next/link'
5
+ import Image from 'next/image'
6
+ import { SearchTrigger } from './search-dialog'
7
+ import { ThemeToggle } from './theme-toggle'
8
+ import { MobileSidebar } from './mobile-sidebar'
9
+ import { siteConfig } from '@/lib/theme-config'
10
+ import type { Root } from 'fumadocs-core/page-tree'
11
+
12
+ interface DocsHeaderProps {
13
+ tree: Root
14
+ }
15
+
16
+ export function DocsHeader({ tree }: DocsHeaderProps) {
17
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
18
+
19
+ const openMobileMenu = useCallback(() => setIsMobileMenuOpen(true), [])
20
+ const closeMobileMenu = useCallback(() => setIsMobileMenuOpen(false), [])
21
+
22
+ return (
23
+ <>
24
+ <header className="sticky top-0 z-50 w-full border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
25
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
26
+ <div className="flex h-16 items-center justify-between gap-4">
27
+ {/* Left: Hamburger + Logo */}
28
+ <div className="flex items-center gap-2">
29
+ {/* Mobile menu button */}
30
+ <button
31
+ onClick={openMobileMenu}
32
+ className="lg:hidden p-2 -ml-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors min-w-[44px] min-h-[44px] flex items-center justify-center"
33
+ aria-label="Open menu"
34
+ aria-expanded={isMobileMenuOpen}
35
+ >
36
+ <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
37
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
38
+ </svg>
39
+ </button>
40
+
41
+ {/* Logo */}
42
+ <Link href="/" className="flex items-center gap-2">
43
+ {siteConfig.logo.src && (
44
+ <Image
45
+ src={siteConfig.logo.src}
46
+ alt={siteConfig.logo.alt}
47
+ width={siteConfig.logo.width}
48
+ height={siteConfig.logo.height}
49
+ className="dark:invert"
50
+ />
51
+ )}
52
+ <span className="font-semibold text-lg hidden sm:inline">{siteConfig.name}</span>
53
+ </Link>
54
+ </div>
55
+
56
+ {/* Center: Search */}
57
+ <div className="flex-1 flex justify-center px-2 sm:px-4">
58
+ <SearchTrigger />
59
+ </div>
60
+
61
+ {/* Right: Links */}
62
+ <div className="flex items-center gap-1 sm:gap-2">
63
+ {siteConfig.links.github && (
64
+ <a
65
+ href={siteConfig.links.github}
66
+ target="_blank"
67
+ rel="noopener noreferrer"
68
+ className="p-2 text-muted-foreground hover:text-foreground transition-colors min-w-[44px] min-h-[44px] flex items-center justify-center"
69
+ aria-label="GitHub"
70
+ >
71
+ <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
72
+ <path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
73
+ </svg>
74
+ </a>
75
+ )}
76
+ <ThemeToggle />
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </header>
81
+
82
+ {/* Mobile sidebar */}
83
+ <MobileSidebar
84
+ tree={tree}
85
+ isOpen={isMobileMenuOpen}
86
+ onClose={closeMobileMenu}
87
+ />
88
+ </>
89
+ )
90
+ }
@@ -0,0 +1,287 @@
1
+ 'use client'
2
+
3
+ import { useEffect, useRef, useCallback, TouchEvent, useState } from 'react'
4
+ import Link from 'next/link'
5
+ import { usePathname } from 'next/navigation'
6
+ import { cn } from '@/lib/utils'
7
+ import { siteConfig } from '@/lib/theme-config'
8
+ import type { Root, Node } from 'fumadocs-core/page-tree'
9
+
10
+ interface MobileSidebarProps {
11
+ tree: Root
12
+ isOpen: boolean
13
+ onClose: () => void
14
+ }
15
+
16
+ /**
17
+ * Mobile sidebar with slide-in drawer animation
18
+ * - Swipe right to close
19
+ * - Tap backdrop to close
20
+ * - Escape key to close
21
+ * - Auto-close on navigation
22
+ */
23
+ export function MobileSidebar({ tree, isOpen, onClose }: MobileSidebarProps) {
24
+ const pathname = usePathname()
25
+ const panelRef = useRef<HTMLDivElement>(null)
26
+ const touchStart = useRef<{ x: number; y: number; time: number } | null>(null)
27
+ const touchMove = useRef<{ x: number; y: number } | null>(null)
28
+
29
+ // Close on route change
30
+ useEffect(() => {
31
+ onClose()
32
+ }, [pathname, onClose])
33
+
34
+ // Close on escape key
35
+ useEffect(() => {
36
+ const handleKeyDown = (e: KeyboardEvent) => {
37
+ if (e.key === 'Escape' && isOpen) {
38
+ onClose()
39
+ }
40
+ }
41
+
42
+ document.addEventListener('keydown', handleKeyDown)
43
+ return () => document.removeEventListener('keydown', handleKeyDown)
44
+ }, [isOpen, onClose])
45
+
46
+ // Prevent body scroll when open
47
+ useEffect(() => {
48
+ if (isOpen) {
49
+ document.body.style.overflow = 'hidden'
50
+ } else {
51
+ document.body.style.overflow = ''
52
+ }
53
+
54
+ return () => {
55
+ document.body.style.overflow = ''
56
+ }
57
+ }, [isOpen])
58
+
59
+ // Swipe handlers
60
+ const handleTouchStart = useCallback((e: TouchEvent) => {
61
+ const touch = e.touches[0]
62
+ touchStart.current = {
63
+ x: touch.clientX,
64
+ y: touch.clientY,
65
+ time: Date.now(),
66
+ }
67
+ touchMove.current = null
68
+ }, [])
69
+
70
+ const handleTouchMove = useCallback((e: TouchEvent) => {
71
+ const touch = e.touches[0]
72
+ touchMove.current = {
73
+ x: touch.clientX,
74
+ y: touch.clientY,
75
+ }
76
+ }, [])
77
+
78
+ const handleTouchEnd = useCallback(() => {
79
+ if (!touchStart.current || !touchMove.current) return
80
+
81
+ const deltaX = touchMove.current.x - touchStart.current.x
82
+ const deltaY = touchMove.current.y - touchStart.current.y
83
+ const timeElapsed = Date.now() - touchStart.current.time
84
+
85
+ // Calculate velocity
86
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)
87
+ const velocity = distance / timeElapsed
88
+
89
+ // Swipe left to close (when panel is on left side)
90
+ const threshold = 50
91
+ const velocityThreshold = 0.3
92
+
93
+ if (
94
+ Math.abs(deltaX) > Math.abs(deltaY) && // Horizontal swipe
95
+ deltaX < -threshold && // Swiping left
96
+ velocity > velocityThreshold
97
+ ) {
98
+ onClose()
99
+ }
100
+
101
+ touchStart.current = null
102
+ touchMove.current = null
103
+ }, [onClose])
104
+
105
+ return (
106
+ <>
107
+ {/* Backdrop */}
108
+ <div
109
+ className={cn(
110
+ 'fixed inset-0 bg-black/60 z-40 transition-opacity duration-300 lg:hidden',
111
+ isOpen ? 'opacity-100' : 'opacity-0 pointer-events-none'
112
+ )}
113
+ onClick={onClose}
114
+ aria-hidden="true"
115
+ />
116
+
117
+ {/* Sliding panel */}
118
+ <div
119
+ ref={panelRef}
120
+ className={cn(
121
+ 'fixed top-0 left-0 bottom-0 w-80 max-w-[85vw] bg-background border-r border-border z-50 transform transition-transform duration-300 ease-out lg:hidden',
122
+ isOpen ? 'translate-x-0' : '-translate-x-full'
123
+ )}
124
+ onTouchStart={handleTouchStart}
125
+ onTouchMove={handleTouchMove}
126
+ onTouchEnd={handleTouchEnd}
127
+ >
128
+ {/* Header */}
129
+ <div className="flex items-center justify-between h-16 px-4 border-b border-border">
130
+ <Link href="/" className="font-semibold text-lg" onClick={onClose}>
131
+ {siteConfig.name}
132
+ </Link>
133
+ <button
134
+ onClick={onClose}
135
+ className="p-2 -mr-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors min-w-[44px] min-h-[44px] flex items-center justify-center"
136
+ aria-label="Close menu"
137
+ >
138
+ <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
139
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
140
+ </svg>
141
+ </button>
142
+ </div>
143
+
144
+ {/* Navigation */}
145
+ <nav className="h-[calc(100%-4rem)] overflow-y-auto p-4">
146
+ {/* Quick links */}
147
+ <div className="mb-6 pb-5 border-b border-border">
148
+ <ul className="space-y-1">
149
+ <li>
150
+ <Link
151
+ href="/docs"
152
+ onClick={onClose}
153
+ className="flex items-center gap-3 py-2 px-2 text-sm text-[var(--accent)] font-medium hover:bg-[var(--accent-muted)] rounded-md transition-colors min-h-[44px]"
154
+ >
155
+ <span className="flex items-center justify-center w-7 h-7 rounded-md bg-[var(--accent-muted)]">
156
+ <svg className="w-4 h-4 text-[var(--accent)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
157
+ <path strokeLinecap="round" strokeLinejoin="round" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
158
+ </svg>
159
+ </span>
160
+ Documentation
161
+ </Link>
162
+ </li>
163
+ {siteConfig.links.github && (
164
+ <li>
165
+ <a
166
+ href={siteConfig.links.github}
167
+ target="_blank"
168
+ rel="noopener noreferrer"
169
+ className="flex items-center gap-3 py-2 px-2 text-sm text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors min-h-[44px]"
170
+ >
171
+ <span className="flex items-center justify-center w-7 h-7 rounded-md bg-muted">
172
+ <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
173
+ <path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
174
+ </svg>
175
+ </span>
176
+ GitHub
177
+ </a>
178
+ </li>
179
+ )}
180
+ {siteConfig.links.support && (
181
+ <li>
182
+ <a
183
+ href={siteConfig.links.support}
184
+ className="flex items-center gap-3 py-2 px-2 text-sm text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors min-h-[44px]"
185
+ >
186
+ <span className="flex items-center justify-center w-7 h-7 rounded-md bg-muted">
187
+ <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
188
+ <path strokeLinecap="round" strokeLinejoin="round" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
189
+ </svg>
190
+ </span>
191
+ Support
192
+ </a>
193
+ </li>
194
+ )}
195
+ </ul>
196
+ </div>
197
+
198
+ {/* Page tree navigation */}
199
+ <MobileSidebarNodes nodes={tree.children} pathname={pathname} onNavigate={onClose} />
200
+ </nav>
201
+ </div>
202
+ </>
203
+ )
204
+ }
205
+
206
+ interface MobileSidebarNodesProps {
207
+ nodes: Node[]
208
+ pathname: string
209
+ onNavigate: () => void
210
+ }
211
+
212
+ function MobileSidebarNodes({ nodes, pathname, onNavigate }: MobileSidebarNodesProps) {
213
+ return (
214
+ <div className="space-y-1">
215
+ {nodes.map((node, index) => (
216
+ <MobileSidebarNode key={index} node={node} pathname={pathname} onNavigate={onNavigate} />
217
+ ))}
218
+ </div>
219
+ )
220
+ }
221
+
222
+ interface MobileSidebarNodeProps {
223
+ node: Node
224
+ pathname: string
225
+ onNavigate: () => void
226
+ }
227
+
228
+ function MobileSidebarNode({ node, pathname, onNavigate }: MobileSidebarNodeProps) {
229
+ const [isExpanded, setIsExpanded] = useState(true)
230
+
231
+ if (node.type === 'separator') {
232
+ return (
233
+ <div className="pt-4 first:pt-0">
234
+ <h5 className="text-sm font-semibold text-foreground mb-1.5 px-2">
235
+ {node.name}
236
+ </h5>
237
+ </div>
238
+ )
239
+ }
240
+
241
+ if (node.type === 'folder') {
242
+ return (
243
+ <div>
244
+ <button
245
+ onClick={() => setIsExpanded(!isExpanded)}
246
+ className="flex items-center justify-between w-full py-2 px-2 text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors min-h-[44px]"
247
+ >
248
+ <span>{node.name}</span>
249
+ <svg
250
+ className={cn('w-4 h-4 transition-transform', isExpanded && 'rotate-90')}
251
+ fill="none"
252
+ stroke="currentColor"
253
+ viewBox="0 0 24 24"
254
+ >
255
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
256
+ </svg>
257
+ </button>
258
+ {isExpanded && node.children && (
259
+ <ul className="ml-3 mt-1 space-y-0.5 border-l border-border pl-3">
260
+ {node.children.map((child, index) => (
261
+ <MobileSidebarNode key={index} node={child} pathname={pathname} onNavigate={onNavigate} />
262
+ ))}
263
+ </ul>
264
+ )}
265
+ </div>
266
+ )
267
+ }
268
+
269
+ const isActive = pathname === node.url
270
+
271
+ return (
272
+ <li className="list-none">
273
+ <Link
274
+ href={node.url}
275
+ onClick={onNavigate}
276
+ className={cn(
277
+ 'flex items-center gap-2 py-2 px-2 text-sm transition-colors rounded-md min-h-[44px]',
278
+ isActive
279
+ ? 'text-[var(--accent)] font-medium bg-[var(--accent-muted)]'
280
+ : 'text-muted-foreground hover:text-foreground hover:bg-muted'
281
+ )}
282
+ >
283
+ <span>{node.name}</span>
284
+ </Link>
285
+ </li>
286
+ )
287
+ }
@@ -1,9 +1,6 @@
1
- import Link from 'next/link'
2
- import Image from 'next/image'
3
1
  import { source } from '@/lib/docs-source'
4
2
  import { DocsSidebar } from '../components/docs/docs-sidebar'
5
- import { SearchTrigger } from '../components/docs/search-dialog'
6
- import { ThemeToggle } from '../components/docs/theme-toggle'
3
+ import { DocsHeader } from '../components/docs/docs-header'
7
4
  import { siteConfig } from '@/lib/theme-config'
8
5
 
9
6
  export default function DocsLayout({
@@ -15,48 +12,8 @@ export default function DocsLayout({
15
12
 
16
13
  return (
17
14
  <div className="min-h-screen flex flex-col">
18
- {/* Header */}
19
- <header className="sticky top-0 z-50 w-full border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
20
- <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
21
- <div className="flex h-16 items-center justify-between">
22
- {/* Logo */}
23
- <Link href="/" className="flex items-center gap-2">
24
- {siteConfig.logo.src && (
25
- <Image
26
- src={siteConfig.logo.src}
27
- alt={siteConfig.logo.alt}
28
- width={siteConfig.logo.width}
29
- height={siteConfig.logo.height}
30
- className="dark:invert"
31
- />
32
- )}
33
- <span className="font-semibold text-lg">{siteConfig.name}</span>
34
- </Link>
35
-
36
- {/* Center: Search */}
37
- <div className="flex-1 flex justify-center px-4">
38
- <SearchTrigger />
39
- </div>
40
-
41
- {/* Right: Links */}
42
- <div className="flex items-center gap-2">
43
- {siteConfig.links.github && (
44
- <a
45
- href={siteConfig.links.github}
46
- target="_blank"
47
- rel="noopener noreferrer"
48
- className="p-2 text-muted-foreground hover:text-foreground transition-colors"
49
- >
50
- <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
51
- <path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
52
- </svg>
53
- </a>
54
- )}
55
- <ThemeToggle />
56
- </div>
57
- </div>
58
- </div>
59
- </header>
15
+ {/* Header with mobile navigation */}
16
+ <DocsHeader tree={tree} />
60
17
 
61
18
  {/* Main content */}
62
19
  <div className="flex-1">
@@ -49,7 +49,7 @@ Unmint is designed to be forked and customized. All the code is yours to modify.
49
49
 
50
50
  ```bash
51
51
  # Clone the repository
52
- git clone https://github.com/your-org/unmint.git my-docs
52
+ git clone https://github.com/gregce/unmint.git my-docs
53
53
 
54
54
  # Install dependencies
55
55
  cd my-docs
@@ -20,7 +20,7 @@ Before you begin, make sure you have:
20
20
  Start by cloning the Unmint template:
21
21
 
22
22
  ```bash
23
- git clone https://github.com/your-org/unmint.git my-docs
23
+ git clone https://github.com/gregce/unmint.git my-docs
24
24
  cd my-docs
25
25
  ```
26
26
  </Step>
@@ -18,7 +18,7 @@
18
18
  "fumadocs-core": "^16.4.7",
19
19
  "fumadocs-mdx": "^14.2.5",
20
20
  "lucide-react": "^0.483.0",
21
- "next": "^15.5.7",
21
+ "next": "^16.0.0",
22
22
  "next-themes": "^0.4.6",
23
23
  "react": "^19.0.0",
24
24
  "react-dom": "^19.0.0",
@@ -35,8 +35,8 @@
35
35
  "@vitejs/plugin-react": "^4.3.4",
36
36
  "autoprefixer": "^10.4.21",
37
37
  "eslint": "^9",
38
- "eslint-config-next": "^15.5.7",
39
- "happy-dom": "^17.4.4",
38
+ "eslint-config-next": "^16.0.0",
39
+ "happy-dom": "^20.3.4",
40
40
  "postcss": "^8.5.4",
41
41
  "tailwindcss": "^4",
42
42
  "typescript": "^5",
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2017",
4
- "lib": ["dom", "dom.iterable", "esnext"],
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
5
9
  "allowJs": true,
6
10
  "skipLibCheck": true,
7
11
  "strict": true,
@@ -11,7 +15,7 @@
11
15
  "moduleResolution": "bundler",
12
16
  "resolveJsonModule": true,
13
17
  "isolatedModules": true,
14
- "jsx": "preserve",
18
+ "jsx": "react-jsx",
15
19
  "incremental": true,
16
20
  "plugins": [
17
21
  {
@@ -19,7 +23,9 @@
19
23
  }
20
24
  ],
21
25
  "paths": {
22
- "@/*": ["./*"]
26
+ "@/*": [
27
+ "./*"
28
+ ]
23
29
  }
24
30
  },
25
31
  "include": [
@@ -27,7 +33,10 @@
27
33
  "**/*.ts",
28
34
  "**/*.tsx",
29
35
  ".next/types/**/*.ts",
30
- ".source/**/*.ts"
36
+ ".source/**/*.ts",
37
+ ".next/dev/types/**/*.ts"
31
38
  ],
32
- "exclude": ["node_modules"]
39
+ "exclude": [
40
+ "node_modules"
41
+ ]
33
42
  }