# @hiyve/react-notes

Rich text meeting notes editor with auto-save and PDF export for Hiyve.

## Installation

```bash
npx @hiyve/cli login
npm install @hiyve/react-notes
```

## Quick Start

```tsx
import { NoteEditor } from '@hiyve/react-notes';
import { HiyveProvider } from '@hiyve/react';

function MeetingNotes() {
  return (
    <HiyveProvider token={roomToken}>
      <NoteEditor
        title="Meeting Notes"
        enableAutoSave
        onSave={(note) => console.log('Saved:', note.id)}
      />
    </HiyveProvider>
  );
}
```

## Components

| Component | Description |
|-----------|-------------|
| `NoteEditor` | Full-featured rich text editor with toolbar, title input, auto-save, and PDF export |
| `NoteEditorToolbar` | Standalone formatting toolbar (bold, italic, headings, lists, tables, etc.) |
| `NotesSession` | Session manager that pairs a NoteEditor with file loading, creation, and header controls |
| `NotesSessionViewer` | Read-only viewer for saved note files, suitable for file manager integration |

## Dialogs

### CreateNoteDialog

Dialog for creating a new note with a custom name. Handles file creation via the client API and calls back with the new file ID and data.

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `boolean` | -- | Whether the dialog is open |
| `onClose` | `() => void` | -- | Called when the dialog closes |
| `onCreate` | `(fileId: string, fileName: string, fileData: NoteFile) => void` | -- | Called when note is created successfully |
| `defaultName` | `string` | `''` | Default name for the note |
| `isCreating` | `boolean` | -- | External control for creation-in-progress state |
| `error` | `string \| null` | -- | External error message to display |
| `labels` | `Partial<CreateNoteDialogLabels>` | -- | Custom labels for i18n |

## Hooks

| Hook | Description |
|------|-------------|
| `useNoteEditor` | Sets up a rich text editor instance with extensions and content tracking |
| `useNotePersistence` | Manages auto-save, manual save, and save status tracking |

## Utilities

| Export | Description |
|--------|-------------|
| `exportNoteToPdf` | Exports note content to a downloadable PDF file |
| `generateNoteId` | Creates a unique note identifier |
| `isContentEmpty` | Checks whether editor content is empty or whitespace-only |
| `defaultFormatTimestamp` | Formats a timestamp as relative time ("2m ago", "Jan 15") |
| `getEditorStyles` | Returns CSS styles for the editor area |
| `createNoteFile(client, options)` | Creates a new note file and uploads it to the server. Returns `{ fileId, fileData }` |

## NoteEditor Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `title` | `string` | `'Notes'` | Header title for the notes panel |
| `initialTitle` | `string` | -- | Pre-filled title for the note |
| `initialContent` | `JSONContent` | -- | Pre-filled editor content |
| `placeholder` | `string` | `'Start typing...'` | Placeholder when editor is empty |
| `showHeader` | `boolean` | `true` | Show the panel header |
| `showToolbar` | `boolean` | `true` | Show the formatting toolbar |
| `showTitleInput` | `boolean` | `true` | Show the title input field |
| `maxHeight` | `number \| string` | -- | Maximum height before scrolling |
| `minHeight` | `number \| string` | -- | Minimum editor height |
| `disabled` | `boolean` | `false` | Disable the entire panel |
| `readOnly` | `boolean` | `false` | Make the editor read-only |
| `enableAutoSave` | `boolean` | `false` | Enable auto-save to file storage |
| `autoSaveInterval` | `number` | `3000` | Auto-save interval in milliseconds |
| `fileId` | `string` | -- | Existing file ID (for editing a saved note) |
| `fileLocation` | `string` | `'/Notes'` | Storage folder path |
| `enablePdfExport` | `boolean` | `true` | Show PDF export button |
| `enableTableSupport` | `boolean` | `true` | Enable table editing |
| `enableTaskLists` | `boolean` | `true` | Enable task list (checkbox) support |
| `enableHighlight` | `boolean` | `true` | Enable text highlighting |
| `labels` | `Partial<NoteEditorLabels>` | -- | Label overrides for i18n |
| `icons` | `Partial<NoteEditorIcons>` | -- | Icon overrides |
| `colors` | `Partial<NoteEditorColors>` | -- | Color overrides |
| `styles` | `Partial<NoteEditorStyles>` | -- | Style overrides |
| `renderProps` | `NoteEditorRenderProps` | -- | Render props for header, toolbar, and save status |
| `sx` | `SxProps<Theme>` | -- | MUI sx prop for the container |
| `onChange` | `(content: JSONContent) => void` | -- | Called when content changes |
| `onTitleChange` | `(title: string) => void` | -- | Called when the title changes |
| `onSave` | `(note: NoteFile) => void` | -- | Called after a successful save |
| `onSaveError` | `(error: Error) => void` | -- | Called when a save fails |
| `onAutoSave` | `(fileId: string) => void` | -- | Called after a successful auto-save |
| `onFocus` | `() => void` | -- | Called when the editor gains focus |
| `onBlur` | `() => void` | -- | Called when the editor loses focus |

## Imperative Handle (Ref)

`NoteEditor` exposes a ref for external control:

```tsx
import { useRef } from 'react';
import { NoteEditor, type NoteEditorRef } from '@hiyve/react-notes';

function NotesPanel() {
  const editorRef = useRef<NoteEditorRef>(null);

  return (
    <div>
      <button
        onClick={() => editorRef.current?.save()}
        disabled={editorRef.current?.isSaving}
      >
        Save Now
      </button>
      <NoteEditor ref={editorRef} enableAutoSave />
    </div>
  );
}
```

The ref provides: `save()`, `isSaving`, `hasUnsavedChanges`, `lastSaved`, and `fileId`.

## Using Hooks Directly

For custom editor UIs, use the hooks independently:

```tsx
import { useNoteEditor, useNotePersistence } from '@hiyve/react-notes';

function CustomNoteEditor() {
  const { editor, content, isEmpty, getHTML, focus } = useNoteEditor({
    placeholder: 'Start typing...',
    onUpdate: (content) => console.log('Changed'),
  });

  // Render your own UI around the editor instance
}
```

## PDF Export

```tsx
import { exportNoteToPdf } from '@hiyve/react-notes';

async function handleExport() {
  await exportNoteToPdf({
    title: 'Sprint Planning Notes',
    htmlContent: editor.getHTML(),
    authorName: 'Jane Doe',
    pageSize: 'letter',
    orientation: 'portrait',
  });
}
```

## Session Management

`NotesSession` provides a complete session workflow -- creating new notes, loading saved notes from file storage, and editing with auto-save:

```tsx
import { NotesSession } from '@hiyve/react-notes';

<NotesSession
  labels={{
    emptyState: { message: 'No note open', createButton: 'Create New' },
    header: { newSession: 'New Note' },
  }}
  noteEditorProps={{
    enableAutoSave: true,
    autoSaveInterval: 5000,
  }}
/>
```

`NotesSessionViewer` renders a saved note in read-only mode:

```tsx
import { NotesSessionViewer } from '@hiyve/react-notes';

<NotesSessionViewer note={savedNoteFile} maxHeight={400} />
```

## Customization

All visual aspects of the editor are customizable through `labels`, `icons`, `colors`, and `styles` props. Pass a partial object -- unspecified keys use defaults.

### Labels (i18n)

```tsx
import { NoteEditor } from '@hiyve/react-notes';

<NoteEditor
  labels={{
    title: 'Notas',
    placeholder: 'Escribe tus notas...',
    save: 'Guardar',
    exportPdf: 'Exportar PDF',
    saving: 'Guardando...',
    saved: 'Guardado',
    bold: 'Negrita',
    italic: 'Cursiva',
  }}
/>
```

### Icons

```tsx
import { NoteEditor } from '@hiyve/react-notes';
import { FaBold, FaItalic } from 'react-icons/fa';

<NoteEditor
  icons={{
    bold: <FaBold />,
    italic: <FaItalic />,
  }}
/>
```

### Colors

```tsx
import { NoteEditor, defaultNoteEditorColors } from '@hiyve/react-notes';

// Light theme
<NoteEditor
  colors={{
    headerBackground: '#f5f5f5',
    editorBackground: '#ffffff',
    editorText: '#212121',
    toolbarBackground: '#fafafa',
    toolbarButtonActive: '#1976d2',
  }}
/>
```

### Styles

```tsx
import { NoteEditor } from '@hiyve/react-notes';

// Compact layout
<NoteEditor
  styles={{
    toolbarButtonSize: 28,
    editorPadding: 12,
    editorFontSize: '0.875rem',
    borderRadius: 8,
  }}
/>
```

### Render Props

Override rendering of the header, toolbar, or save status indicator:

```tsx
<NoteEditor
  renderProps={{
    renderHeader: (title, defaultContent) => (
      <div style={{ display: 'flex', alignItems: 'center' }}>
        <MyLogo />
        {defaultContent}
      </div>
    ),
    renderToolbar: (editor, defaultContent) => (
      <div>
        {defaultContent}
        <button onClick={() => editor?.chain().focus().toggleBold().run()}>
          Custom Bold
        </button>
      </div>
    ),
  }}
/>
```

**Defaults and merge functions:**

| Default | Merge Function |
|---------|---------------|
| `defaultNoteEditorLabels` | `mergeNoteEditorLabels` |
| `defaultNoteEditorIcons` | `mergeNoteEditorIcons` |
| `defaultNoteEditorColors` | `mergeNoteEditorColors` |
| `defaultNoteEditorStyles` | `mergeNoteEditorStyles` |
| `defaultNotesSessionLabels` | -- |

## Features

- Rich text formatting (bold, italic, strikethrough, highlight, code)
- Headings (H1, H2, H3)
- Lists (bullet, numbered, task/checkbox)
- Tables with full editing (add/remove rows and columns)
- Blockquotes and horizontal rules
- Auto-save to file storage with debouncing
- PDF export with configurable page size and orientation
- Undo/redo history
- Read-only mode for viewing saved notes
- Dark theme matching other Hiyve components

## Constants

| Constant | Description |
|----------|-------------|
| `DEFAULT_AUTO_SAVE_INTERVAL` | Default auto-save interval (3000ms) |
| `DEFAULT_PLACEHOLDER` | Default placeholder text |
| `DEFAULT_FILE_LOCATION` | Default storage folder (`'/Notes'`) |
| `DEFAULT_TABLE_DIMENSIONS` | Default rows/columns for new tables |
| `NOTE_FILE_EXTENSION` | File extension for note files |
| `NOTE_FILE_MIME_TYPE` | MIME type for note files |
| `EMPTY_CONTENT` | Empty document structure for initializing the editor |
| `CONTENT_CHANGE_DEBOUNCE` | Debounce interval for content change events (500ms) |

## Requirements

- **`@hiyve/react`** (`^2.0.0`) -- components must be rendered inside `HiyveProvider`
- **`@hiyve/react-collaboration`** (`^1.0.0`) -- optional, needed for `NotesSession` and `NotesSessionViewer`
- **`@hiyve/utilities`** (`^1.0.0`)
- **`@mui/material`** (`^5.0.0 || ^6.0.0`) and **`@mui/icons-material`**
- **`@emotion/react`** (`^11.0.0`) and **`@emotion/styled`** (`^11.0.0`)
- **`react`** (`^18.0.0`)

Rich text editor dependencies are bundled with the package -- no separate installation needed.

## License

Proprietary - Hiyve SDK
