# Editor Toolbar

This page covers the floating toolbar built by `editorTab`: where it appears, its buttons, and the image upload button enabled through `event.upload`.

## Placement

The toolbar is a `<section class="input-button">` (`contentEditable=false`) inside the editor container, using Material Symbols icons.

| State | Behavior |
|---|---|
| Caret enters a row | The toolbar moves directly below that row, `data-hide="0"` |
| Editor loses focus | The toolbar moves to the end of the container, `data-hide="1"` |
| `tabPin` truthy or pin pressed | The container gets `data-pin="1"` and CSS keeps the toolbar visible |

Buttons are bound to `pointerup` rather than `click`; their `title` tooltips are hard-coded in Traditional Chinese.

## Buttons

| Icon | Calls | Shown when |
|---|---|---|
| `format_bold` | `bold()` | Always |
| `format_italic` | `italic()` | Always |
| `strikethrough_s` | `strikethrough()` | Always |
| `format_underlined` | `underline()` | Always |
| `ink_marker` | `marker()` | Always |
| `superscript` | `sup()` | Always |
| `subscript` | `sub()` | Always |
| `format_quote` | `blockquote()` | Always |
| `format_list_bulleted` | `ul()` | Always |
| `format_list_numbered` | `ol()` | Always |
| `code` | `code()` | Always |
| `link` | `link("連結文字", "連結")` | Always; inserts placeholder text for the user to edit |
| `landscape` | `image("圖片連結", "圖片名稱")` | Always; inserts `![圖片名稱](圖片連結)` |
| `smb_share` | `event.upload()` then `image()` | `event.upload` is set |
| `autorenew` | `save()` | `autosave` is false |
| `keep` / `keep_off` | Toggles `data-pin` | Always |
| `wrap_text` | Toggles `data-wrap` | Always |
| `cloud_upload` | Deploy | Only when the URL contains `nanomd.pardn.io` |

Toolbar events carry no modifier key, so the buttons insert Markdown markers.

## Image Upload

```javascript
const editor = new MDEditor({
    id: "editor",
    event: {
        upload: async () => {
            const file = await pickFile();
            const res = await fetch("/api/upload", { method: "POST", body: file });
            const { url } = await res.json();
            return { href: url, alt: file.name };
        }
    }
});
```

| Rule | Detail |
|---|---|
| Arguments | `upload()` receives none; file picking and uploading are up to you |
| Return value | An object `{ href, alt }`; a missing `href` becomes an empty string, a missing `alt` becomes `"測試"` |
| Empty `href` | `image()` ignores it and inserts nothing |
| Errors | A rejected `upload()` is not caught and surfaces as an unhandled Promise rejection |

## Deploy Button

`cloud_upload` serves only the nanomd.pardn.io online editor: it POSTs the converted HTML to `nanomd-deploy.pardn.workers.dev` and, on success, offers to open the page on `nanomd-cloud.pardn.workers.dev`. It never appears when embedded on other sites.
