# AppEditor

## Overview

Rich text editor powered by Lexical with optional Markdown sync. Supports configurable toolbars (block format, font format, history), clear action, character counter, and extended Markdown syntax including underline support.

---

## Props

| Prop             | Type                         | Default                                               | Description                                                                                             |
| ---------------- | ---------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ---------------------- |
| `defaultValue`   | `string`                     | `undefined`                                           | Initial content. Interpreted as Markdown when `onlyMarkdown=true`, plain text otherwise.                |
| `onMarkdownEdit` | `(markdown: string) => void` | `undefined`                                           | Emits current content as Markdown on change.                                                            |
| `plugins`        | `("clear"                    | "counter")[]`                                         | `[]`                                                                                                    | Enable optional plugins: clear buttons, character counter. |
| `toolbars`       | `("block-format"             | "font-format"                                         | "history")[]`                                                                                           | `[]`                                                       | Enable toolbar groups. |
| `placeholder`    | `string`                     | `"Start typing..."`                                   | Placeholder for empty editor.                                                                           |
| `onlyMarkdown`   | `boolean`                    | `true`                                                | Treat `defaultValue` as Markdown and sync editor to Markdown. If `false`, `defaultValue` is plain text. |
| `className`      | `string`                     | `"overflow-hidden rounded-lg border border-d-border"` | Extra classes for the content editable.                                                                 |

---

## Behavior

- **Markdown sync**: When `onlyMarkdown=true`, initializes from Markdown and emits Markdown on every change.
- **Extended Markdown**: Supports standard Markdown plus underline syntax using `<u>text</u>` (e.g., `<u>underlined text</u>`).
- **Toolbars**:
  - `history`: undo/redo toolbar.
  - `block-format`: heading levels (h1-h3), numbered/bulleted/check lists, blockquote.
  - `font-format`: bold, italic, underline, strikethrough, inline code.
- **Plugins**:
  - `clear`: clear actions in the footer.
  - `counter`: UTF-16 character counter in the footer.
- **Editing**: Autosave via `onMarkdownEdit`. Keyboard navigation and selection per Lexical defaults.
- **Markdown Features**: Full support for headings, lists, quotes, links, inline code, bold, italic, strikethrough, and custom underline syntax.

---

## Examples

### Full Toolbar + Plugins

```tsx
import * as React from "react";
import { AppEditor } from "laif-ds";

export function EditorFull() {
  const [markdown, setMarkdown] = React.useState("Hello world");
  return (
    <div className="space-y-4">
      <AppEditor
        defaultValue={markdown}
        onMarkdownEdit={setMarkdown}
        toolbars={["block-format", "font-format", "history"]}
        plugins={["clear", "counter"]}
        className="h-96"
      />
      <div className="text-d-muted-foreground text-sm">
        <span className="font-medium">Current markdown:</span>{" "}
        {markdown || "(empty)"}
      </div>
    </div>
  );
}
```

### Markdown Default Value

```tsx
import * as React from "react";
import { AppEditor } from "laif-ds";

export function MarkdownDefault() {
  const initial = "**Titolo** con testo in <u>markdown</u> e *corsivo*";
  const [md, setMd] = React.useState(initial);
  return (
    <AppEditor
      defaultValue={initial}
      onMarkdownEdit={setMd}
      toolbars={["block-format", "font-format", "history"]}
    />
  );
}
```

### Underline Support

```tsx
import * as React from "react";
import { AppEditor } from "laif-ds";

export function UnderlineExample() {
  const initial = "Testo normale <u>testo sottolineato</u> altro normale";
  const [md, setMd] = React.useState(initial);
  return (
    <AppEditor
      defaultValue={initial}
      onMarkdownEdit={setMd}
      toolbars={["font-format"]}
    />
  );
}
```

---

## Notes

- **Sizing**: Control height via `className` (e.g., `h-96`). Default height is `h-72`.
- **Performance**: Prefer Markdown mode for content pipelines that store Markdown; use `onlyMarkdown=false` for plain text initialization.
- **Accessibility**: Toolbar buttons and editor area follow Lexical best practices.
- **Underline Syntax**: Uses `<u>text</u>` HTML tags for underline, which is standard HTML and natively supported by both this component and `MarkdownRenderer` via `rehype-raw`.
- **Theme**: Uses design system tokens for consistent styling with `border-d-border`, `bg-d-background`, etc.
