Files
tolaria/src/components/CreateNoteDialog.tsx
lucaronin 8cb382e3a3 fix: resolve React hooks/compiler ESLint errors
- Wrap ref assignments in useEffect to fix refs-during-render in
  useTabManagement, useKeyboardNavigation, and Editor
- Rewrite useAppKeyboard to define keyMap inside useEffect, eliminating
  ref access during render
- Add eslint-disable for react-hooks/set-state-in-effect on legitimate
  dialog reset patterns (CommitDialog, CreateNoteDialog, CreateTypeDialog,
  QuickOpenPalette, AIChatPanel, useVaultLoader)
- Add eslint-disable for react-hooks/static-components on icon lookups
  (NoteItem, NoteList PinnedCard) — stateless icon components from a
  static map
- Add eslint-disable for react-hooks/purity on Date.now() in
  NoteItem TrashDateLine — intentionally memoized on trashedAt
- Remove unused `model` param from buildSystemPrompt (ai-chat.ts) and
  update callers
- Fix exhaustive-deps: suppress vault object dep in App.tsx git history
  effect (vault object is unstable, loadGitHistory is the real dep)
- Remove unused `modifiedFiles` from useNoteListData params and caller
- Add missing `ref` to Sidebar useOutsideClick deps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 14:06:51 +01:00

120 lines
3.8 KiB
TypeScript

import { useState, useRef, useEffect } from 'react'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { cn } from '@/lib/utils'
const BUILT_IN_TYPES = [
'Note',
'Project',
'Experiment',
'Responsibility',
'Procedure',
'Person',
'Event',
'Topic',
] as const
export type NoteType = (typeof BUILT_IN_TYPES)[number]
interface CreateNoteDialogProps {
open: boolean
onClose: () => void
onCreate: (title: string, type: string) => void
defaultType?: string
/** Custom types from the vault (Type documents not in built-in list) */
customTypes?: string[]
}
export function CreateNoteDialog({ open, onClose, onCreate, defaultType, customTypes = [] }: CreateNoteDialogProps) {
const [title, setTitle] = useState('')
const [type, setType] = useState<string>('Note')
const inputRef = useRef<HTMLInputElement>(null)
useEffect(() => {
if (open) {
// eslint-disable-next-line react-hooks/set-state-in-effect -- reset on dialog open
setTitle(''); setType(defaultType ?? 'Note')
setTimeout(() => inputRef.current?.focus(), 50)
}
}, [open, defaultType])
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
const trimmed = title.trim()
if (!trimmed) return
onCreate(trimmed, type)
onClose()
}
return (
<Dialog open={open} onOpenChange={(isOpen) => { if (!isOpen) onClose() }}>
<DialogContent showCloseButton={false} className="sm:max-w-[420px]">
<DialogHeader>
<DialogTitle>Create New Note</DialogTitle>
</DialogHeader>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-1.5">
<label className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
Title
</label>
<Input
ref={inputRef}
placeholder="Enter note title..."
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
</div>
<div className="space-y-1.5">
<label className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
Type
</label>
<div className="flex flex-wrap gap-1.5">
{BUILT_IN_TYPES.map((t) => (
<Button
key={t}
type="button"
variant={type === t ? 'default' : 'outline'}
size="sm"
className={cn(
"rounded-full text-xs",
type === t && "bg-primary text-primary-foreground"
)}
onClick={() => setType(t)}
>
{t}
</Button>
))}
{customTypes.map((t) => (
<Button
key={t}
type="button"
variant={type === t ? 'default' : 'outline'}
size="sm"
className={cn(
"rounded-full text-xs",
type === t
? "bg-[var(--accent-blue)] text-white"
: "border-[var(--accent-blue)] text-[var(--accent-blue)]"
)}
onClick={() => setType(t)}
>
{t}
</Button>
))}
</div>
</div>
<DialogFooter>
<Button type="button" variant="outline" onClick={onClose}>
Cancel
</Button>
<Button type="submit" disabled={!title.trim()}>
Create
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
)
}