Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@
# testing
/coverage

# next.js
# build outputs
/.next/
/out/

# production
/.output/
/build

# misc
Expand Down
67 changes: 0 additions & 67 deletions app/layout.tsx

This file was deleted.

26 changes: 21 additions & 5 deletions components/ui/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,27 @@ function Calendar({
...classNames,
}}
components={{
IconLeft: ({ className, ...props }) => (
<ChevronLeft className={cn("size-4", className)} {...props} />
),
IconRight: ({ className, ...props }) => (
<ChevronRight className={cn("size-4", className)} {...props} />
Nav: ({ onPreviousClick, onNextClick, previousMonth, nextMonth }) => (
<div className="flex items-center gap-1">
<button
type="button"
onClick={(event) => onPreviousClick?.(event)}
disabled={!previousMonth}
className={cn(buttonVariants({ variant: "ghost" }), "h-7 w-7 p-0")}
aria-label="Go to previous month"
>
<ChevronLeft className="size-4" />
</button>
<button
type="button"
onClick={(event) => onNextClick?.(event)}
disabled={!nextMonth}
className={cn(buttonVariants({ variant: "ghost" }), "h-7 w-7 p-0")}
aria-label="Go to next month"
>
<ChevronRight className="size-4" />
</button>
</div>
),
}}
{...props}
Expand Down
39 changes: 36 additions & 3 deletions components/ui/sonner.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
"use client"

import { useTheme } from "next-themes"
import { useEffect, useState } from "react"
import { Toaster as Sonner, ToasterProps } from "sonner"

type ThemeMode = NonNullable<ToasterProps["theme"]>

const getDocumentTheme = (): ThemeMode => {
if (typeof document === "undefined") {
return "system"
}

if (document.documentElement.classList.contains("dark")) {
return "dark"
}

if (document.documentElement.classList.contains("light")) {
return "light"
}

return "system"
}

const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme()
const [theme, setTheme] = useState<ThemeMode>("system")

useEffect(() => {
setTheme(getDocumentTheme())

const observer = new MutationObserver(() => {
setTheme(getDocumentTheme())
})

observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["class"],
})

return () => observer.disconnect()
}, [])

return (
<Sonner
theme={theme as ToasterProps["theme"]}
theme={theme}
className="toaster group"
style={
{
Expand Down
21 changes: 11 additions & 10 deletions components/writing-area.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client'

import React, { useEffect, useCallback, useRef } from 'react'
import dynamic from 'next/dynamic'
import React, { useEffect, useCallback, useRef, Suspense } from 'react'
import { MDXEditorMethods } from '@mdxeditor/editor'
import { Button } from './ui/button'
import { writeTextFile, readTextFile } from '@tauri-apps/plugin-fs'
Expand All @@ -21,7 +20,7 @@ import { toast } from 'sonner'
import { useHotkeys } from 'react-hotkeys-hook'
import { S3ConfigDialog } from './s3-config-dialog'

const MarkdownEditor = dynamic(() => import('./markdown-editor'), { ssr: false })
const MarkdownEditor = React.lazy(() => import('./markdown-editor'))

export function WritingArea() {
const { t } = useI18n()
Expand Down Expand Up @@ -302,13 +301,15 @@ export function WritingArea() {
>
{showEditor && (
<div className="h-full min-h-0">
<MarkdownEditor
editorRef={editorRef}
markdown={markdown}
onChange={handleContentChange}
placeholder={t('editor.placeholder') || 'Start writing...'}
folderPath={folderPath}
/>
<Suspense fallback={null}>
<MarkdownEditor
editorRef={editorRef}
markdown={markdown}
onChange={handleContentChange}
placeholder={t('editor.placeholder') || 'Start writing...'}
folderPath={folderPath}
/>
</Suspense>
</div>
)}
{showPreview && (
Expand Down
9 changes: 8 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ const compat = new FlatCompat({
});

const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
...compat.extends("eslint:recommended", "plugin:react/recommended", "plugin:react-hooks/recommended"),
{
settings: {
react: {
version: "detect",
},
},
},
];

export default eslintConfig;
9 changes: 4 additions & 5 deletions hooks/useGlobalEventListeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ export function useGlobalEventListeners() {

// --- Conditionally add keydown listener (only NOT in development) ---
let isKeyDownListenerAdded = false;
if (process.env.NODE_ENV !== 'development') {
window.addEventListener('keydown', handleKeyDown);
isKeyDownListenerAdded = true;
} else {
console.log('Running in development mode, F12 blocking is disabled.');
const isDev = import.meta.env.DEV
if (!isDev) {
window.addEventListener('keydown', handleKeyDown)
isKeyDownListenerAdded = true
}

// --- Cleanup function ---
Expand Down
16 changes: 0 additions & 16 deletions next.config.ts

This file was deleted.

30 changes: 20 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
"name": "onlywrite-app",
"version": "0.1.6",
"private": true,
"type": "module",
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint",
"dev": "vite dev",
"build": "vite build && tsc --noEmit",
"preview": "vite preview",
"start": "node .output/server/index.mjs",
"lint": "eslint .",
"test": "vitest run",
"test:watch": "vitest",
"test:ui": "vitest --ui",
Expand All @@ -20,6 +22,9 @@
"@dnd-kit/utilities": "^3.2.2",
"@hookform/resolvers": "^5.0.1",
"@mdxeditor/editor": "^3.40.1",
"@fontsource-variable/playfair-display": "^5.0.28",
"@fontsource-variable/source-serif-4": "^5.0.30",
"@fontsource-variable/jetbrains-mono": "^5.0.30",
"@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-alert-dialog": "^1.1.6",
"@radix-ui/react-aspect-ratio": "^1.1.2",
Expand Down Expand Up @@ -47,6 +52,8 @@
"@radix-ui/react-toggle-group": "^1.1.2",
"@radix-ui/react-tooltip": "^1.1.8",
"@tabler/icons-react": "^3.31.0",
"@tanstack/react-router": "^1.153.2",
"@tanstack/react-start": "^1.154.0",
"@tanstack/react-table": "^8.21.2",
"@tauri-apps/api": "^2.4.1",
"@tauri-apps/plugin-dialog": "^2.2.1",
Expand All @@ -58,14 +65,12 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.5.2",
"input-otp": "^1.4.2",
"lucide-react": "^0.487.0",
"next": "15.4.10",
"next-themes": "^0.4.6",
"react": "^19.0.0",
"react-day-picker": "8.10.1",
"react-day-picker": "^9.0.0",
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Upgrading react-day-picker from v8 to v9 will break the Calendar component. The existing code in components/ui/calendar.tsx uses v8 API (classNames like caption_label, nav_button_previous, day_selected, etc. and the Nav component API). Version 9 has a completely different API that is not backwards compatible. Either keep v8 or update the Calendar component to use v9 API.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 73:

<comment>Upgrading `react-day-picker` from v8 to v9 will break the Calendar component. The existing code in `components/ui/calendar.tsx` uses v8 API (classNames like `caption_label`, `nav_button_previous`, `day_selected`, etc. and the `Nav` component API). Version 9 has a completely different API that is not backwards compatible. Either keep v8 or update the Calendar component to use v9 API.</comment>

<file context>
@@ -58,14 +65,12 @@
-    "next-themes": "^0.4.6",
     "react": "^19.0.0",
-    "react-day-picker": "8.10.1",
+    "react-day-picker": "^9.0.0",
     "react-dom": "^19.0.0",
     "react-hook-form": "^7.55.0",
</file context>
Suggested change
"react-day-picker": "^9.0.0",
"react-day-picker": "8.10.1",
Fix with Cubic

"react-dom": "^19.0.0",
"react-hook-form": "^7.55.0",
"react-hotkeys-hook": "^5.2.1",
Expand All @@ -84,21 +89,26 @@
"@eslint/eslintrc": "^3",
"@playwright/test": "^1.55.0",
"@tailwindcss/postcss": "^4",
"@tailwindcss/vite": "^4.1.18",
"@tauri-apps/cli": "^2.4.1",
"@tauri-apps/plugin-store": "2.4.1",
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^14.6.1",
"@types/node": "^20",
"@types/node": "^22.19.7",
"@types/react": "^19",
"@types/react-dom": "^19",
"@vitejs/plugin-react": "^5.0.2",
"eslint": "^9",
"eslint-config-next": "15.2.4",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"jsdom": "^26.1.0",
"nitro": "npm:nitro-nightly@3.0.1-20260120-020848-6786d069",
"playwright": "^1.55.1",
"tailwindcss": "^4",
"typescript": "^5",
"vite": "^7.3.1",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.2.4"
}
}
Loading