@forgedevstack/ink 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +103 -38
- package/dist/components/InkEditor/InkEditor.cjs +1 -1
- package/dist/components/InkEditor/InkEditor.d.ts.map +1 -1
- package/dist/components/InkEditor/InkEditor.js +495 -156
- package/dist/components/InkEditor/components/AiPanel/AiPanel.cjs +1 -0
- package/dist/components/InkEditor/components/AiPanel/AiPanel.d.ts +11 -0
- package/dist/components/InkEditor/components/AiPanel/AiPanel.d.ts.map +1 -0
- package/dist/components/InkEditor/components/AiPanel/AiPanel.js +178 -0
- package/dist/components/InkEditor/components/AiPanel/index.d.ts +3 -0
- package/dist/components/InkEditor/components/AiPanel/index.d.ts.map +1 -0
- package/dist/components/InkEditor/components/BlockHandles/BlockHandles.cjs +1 -0
- package/dist/components/InkEditor/components/BlockHandles/BlockHandles.d.ts +9 -0
- package/dist/components/InkEditor/components/BlockHandles/BlockHandles.d.ts.map +1 -0
- package/dist/components/InkEditor/components/BlockHandles/BlockHandles.js +12 -0
- package/dist/components/InkEditor/components/BlockHandles/index.d.ts +3 -0
- package/dist/components/InkEditor/components/BlockHandles/index.d.ts.map +1 -0
- package/dist/components/InkEditor/components/CommentsPanel/CommentsPanel.cjs +1 -0
- package/dist/components/InkEditor/components/CommentsPanel/CommentsPanel.d.ts +11 -0
- package/dist/components/InkEditor/components/CommentsPanel/CommentsPanel.d.ts.map +1 -0
- package/dist/components/InkEditor/components/CommentsPanel/CommentsPanel.js +61 -0
- package/dist/components/InkEditor/components/CommentsPanel/index.d.ts +3 -0
- package/dist/components/InkEditor/components/CommentsPanel/index.d.ts.map +1 -0
- package/dist/components/InkEditor/components/SlashMenu/SlashMenu.cjs +1 -0
- package/dist/components/InkEditor/components/SlashMenu/SlashMenu.d.ts +10 -0
- package/dist/components/InkEditor/components/SlashMenu/SlashMenu.d.ts.map +1 -0
- package/dist/components/InkEditor/components/SlashMenu/SlashMenu.js +20 -0
- package/dist/components/InkEditor/components/SlashMenu/index.d.ts +3 -0
- package/dist/components/InkEditor/components/SlashMenu/index.d.ts.map +1 -0
- package/dist/components/InkEditor/components/TrackChangesBar/TrackChangesBar.cjs +1 -0
- package/dist/components/InkEditor/components/TrackChangesBar/TrackChangesBar.d.ts +11 -0
- package/dist/components/InkEditor/components/TrackChangesBar/TrackChangesBar.d.ts.map +1 -0
- package/dist/components/InkEditor/components/TrackChangesBar/TrackChangesBar.js +27 -0
- package/dist/components/InkEditor/components/TrackChangesBar/index.d.ts +3 -0
- package/dist/components/InkEditor/components/TrackChangesBar/index.d.ts.map +1 -0
- package/dist/components/InkEditor/components/index.d.ts +5 -0
- package/dist/components/InkEditor/components/index.d.ts.map +1 -1
- package/dist/constants/aiModels.const.cjs +1 -0
- package/dist/constants/aiModels.const.d.ts +5 -0
- package/dist/constants/aiModels.const.d.ts.map +1 -0
- package/dist/constants/aiModels.const.js +31 -0
- package/dist/constants/defaults.const.cjs +1 -1
- package/dist/constants/defaults.const.d.ts +32 -1
- package/dist/constants/defaults.const.d.ts.map +1 -1
- package/dist/constants/defaults.const.js +124 -20
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/numbers.const.cjs +1 -1
- package/dist/constants/numbers.const.d.ts +13 -0
- package/dist/constants/numbers.const.d.ts.map +1 -1
- package/dist/constants/numbers.const.js +13 -3
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -13
- package/dist/plugins/ai/aiPlugin.cjs +1 -1
- package/dist/plugins/ai/aiPlugin.d.ts.map +1 -1
- package/dist/plugins/ai/aiPlugin.js +40 -18
- package/dist/plugins/ai/demoProvider.cjs +1 -0
- package/dist/plugins/ai/demoProvider.d.ts +3 -0
- package/dist/plugins/ai/demoProvider.d.ts.map +1 -0
- package/dist/plugins/ai/demoProvider.js +130 -0
- package/dist/plugins/ai/index.cjs +1 -1
- package/dist/plugins/ai/index.d.ts +4 -1
- package/dist/plugins/ai/index.d.ts.map +1 -1
- package/dist/plugins/ai/index.js +15 -3
- package/dist/plugins/ai/stubs.cjs +1 -0
- package/dist/plugins/ai/stubs.d.ts +7 -0
- package/dist/plugins/ai/stubs.d.ts.map +1 -0
- package/dist/plugins/ai/stubs.js +23 -0
- package/dist/styles.css +515 -16
- package/dist/types/ai.types.d.ts +111 -2
- package/dist/types/ai.types.d.ts.map +1 -1
- package/dist/types/comments.types.d.ts +17 -0
- package/dist/types/comments.types.d.ts.map +1 -0
- package/dist/types/features.types.d.ts +5 -0
- package/dist/types/features.types.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/ink.types.d.ts +26 -1
- package/dist/types/ink.types.d.ts.map +1 -1
- package/dist/types/trackChanges.types.d.ts +12 -0
- package/dist/types/trackChanges.types.d.ts.map +1 -0
- package/dist/utils/blocks.utils.cjs +1 -0
- package/dist/utils/blocks.utils.d.ts +4 -0
- package/dist/utils/blocks.utils.d.ts.map +1 -0
- package/dist/utils/blocks.utils.js +41 -0
- package/dist/utils/comments.utils.cjs +1 -0
- package/dist/utils/comments.utils.d.ts +5 -0
- package/dist/utils/comments.utils.d.ts.map +1 -0
- package/dist/utils/comments.utils.js +32 -0
- package/dist/utils/history.utils.cjs +1 -0
- package/dist/utils/history.utils.d.ts +13 -0
- package/dist/utils/history.utils.d.ts.map +1 -0
- package/dist/utils/history.utils.js +29 -0
- package/dist/utils/id.utils.cjs +1 -0
- package/dist/utils/id.utils.d.ts +2 -0
- package/dist/utils/id.utils.d.ts.map +1 -0
- package/dist/utils/id.utils.js +4 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/slash.utils.cjs +1 -0
- package/dist/utils/slash.utils.d.ts +4 -0
- package/dist/utils/slash.utils.d.ts.map +1 -0
- package/dist/utils/slash.utils.js +13 -0
- package/dist/utils/table.utils.cjs +1 -0
- package/dist/utils/table.utils.d.ts +2 -0
- package/dist/utils/table.utils.d.ts.map +1 -0
- package/dist/utils/table.utils.js +13 -0
- package/dist/utils/trackChanges.utils.cjs +1 -0
- package/dist/utils/trackChanges.utils.d.ts +7 -0
- package/dist/utils/trackChanges.utils.d.ts.map +1 -0
- package/dist/utils/trackChanges.utils.js +34 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.0 — 2026-08-01
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- CKEditor-inspired editor shell: soft light card, rounded toolbar, `variant="classic" | "document"`
|
|
7
|
+
- Structure blocks with hover/focus outline and block handles (move up/down MVP)
|
|
8
|
+
- Toolbar: table insert, undo/redo, track changes, comments, AI toggles
|
|
9
|
+
- Tables: insert N×M HTML tables with basic editable cells
|
|
10
|
+
- Track changes MVP: `<ins class="Ink-tc-insert">` / `<del class="Ink-tc-delete">`, Accept/Reject strip, `trackChanges` / `onTrackChangesChange`
|
|
11
|
+
- Comments MVP: highlight selection → threaded Comments archive sidebar, `comments` / `onCommentsChange`, `showCommentsPanel`
|
|
12
|
+
- Slash-command MVP: `/` → heading, list, table, AI
|
|
13
|
+
- Features flag object: `features={{ table, trackChanges, comments, ai, blocks, slash, history, typoAutoFix }}`
|
|
14
|
+
- Ink AI suite (`@forgedevstack/ink/plugins/ai`):
|
|
15
|
+
- Capabilities: `chat`, `rewrite`, `summarize`, `expand`, `tone`, `translate`, `review`, `quickAction`, `suggestDiff`
|
|
16
|
+
- Side panel UI via `ai={{ enabled, placement, openOnInit, uiTheme, ... }}`
|
|
17
|
+
- Multi-turn chat history, Quick Actions, Review, Translate, diff preview → apply
|
|
18
|
+
- Provider registry: `inkAi.registerProvider({ id, models, run })`
|
|
19
|
+
- Built-in `demo` provider (deterministic local suggestions, no API keys)
|
|
20
|
+
- Model catalog constants (Claude / Gemini / GPT ids — catalog only; BYO LLM)
|
|
21
|
+
- Architecture stubs: cost control, moderation, permissions, external knowledge, quality eval, fallback chains
|
|
22
|
+
- Exports: `INK_COLLAB_TOOLBAR`, `INK_AI_MODEL_CATALOG`, `buildTableHtml`, comment/track helpers
|
|
23
|
+
|
|
24
|
+
### Docs
|
|
25
|
+
- Feature matrix: CK-inspired capabilities → Ink status (Shipped MVP / Stub / Planned)
|
|
26
|
+
- Honesty framing: CKEditor-inspired architecture with local demo providers; bring your own LLM. No SOC2/enterprise hosting claims.
|
|
27
|
+
|
|
28
|
+
## 1.0.1 — 2026-08-01
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- Theme helper classes: `.ink-theme-snow`, `.ink-theme-bubble`, `.ink-theme-dark`, `.ink-theme-minimal`
|
|
32
|
+
- Expanded README: full prop table, `ToolbarOption` list, CSS variables, Quill positioning, portal links, asset screenshots
|
|
33
|
+
|
|
34
|
+
### Docs
|
|
35
|
+
- Companion light Quill-inspired portal (docs + Format/Modules/Theme playground)
|
|
36
|
+
|
|
3
37
|
## 1.0.0 — 2026-08-01
|
|
4
38
|
|
|
5
39
|
### Added
|
package/README.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
# Ink — `@forgedevstack/ink`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@forgedevstack/ink)
|
|
4
|
+
[](./LICENSE)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
**ForgeStack rich text editor** for React. CKEditor-inspired shell with tables, track changes, comments, block handles, slash commands, and pluggable Ink AI (bring your own LLM + local demo provider).
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<img src="./assets/ink-logo.png" alt="Ink logo" width="120" />
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
> **Domain:** [inkforgejs.com](https://inkforgejs.com) — docs + demos.
|
|
13
|
+
> **Inspired by CKEditor 5** demos / AI features pages and earlier Quill-like portal aesthetics — not a fork. Ink is a contenteditable React component with ForgeStack integrations.
|
|
14
|
+
> **Honesty:** Local demo AI providers only. No hosted enterprise LLM, SOC2, or on-prem claims. Connect Claude / Gemini / GPT (or custom) via `inkAi.registerProvider`.
|
|
7
15
|
|
|
8
16
|
## Install
|
|
9
17
|
|
|
@@ -22,61 +30,118 @@ export function App() {
|
|
|
22
30
|
<InkEditor
|
|
23
31
|
value={value}
|
|
24
32
|
onChange={setValue}
|
|
25
|
-
|
|
33
|
+
variant="classic"
|
|
34
|
+
features={{ table: true, trackChanges: true, comments: true, ai: true, blocks: true, slash: true }}
|
|
35
|
+
ai={{ enabled: true, placement: 'sidebar', openOnInit: true }}
|
|
36
|
+
showCommentsPanel
|
|
26
37
|
typoAutoFix
|
|
27
38
|
/>
|
|
28
39
|
);
|
|
29
40
|
}
|
|
30
41
|
```
|
|
31
42
|
|
|
32
|
-
##
|
|
43
|
+
## Playground & docs
|
|
44
|
+
|
|
45
|
+
| | |
|
|
46
|
+
|---|---|
|
|
47
|
+
| Docs portal | [ink-portal](https://github.com/yaghobieh/ink-portal) · [inkforgejs.com](https://inkforgejs.com) |
|
|
48
|
+
| Demos hub | `/demos` |
|
|
49
|
+
| Ink AI | `/ai` |
|
|
50
|
+
| Live playground | `/playground` |
|
|
51
|
+
| npm | https://www.npmjs.com/package/@forgedevstack/ink |
|
|
52
|
+
| Repo | https://github.com/yaghobieh/ink |
|
|
33
53
|
|
|
34
|
-
|
|
35
|
-
- Toolbar: bold / italic / underline / strike, headings, text + highlight colors, lists, links, image insert/paste
|
|
36
|
-
- **Typo auto-fix MVP** — small bundled dictionary + heuristics (`applyTypoAutoFix`), runs on blur; no heavy proprietary spell engine
|
|
37
|
-
- **AI agent stub** — `@forgedevstack/ink/plugins/ai` register/run interface; full agents coming in **1.x**
|
|
38
|
-
- **Angular** — `@forgedevstack/ink/angular` thin usage helpers / docs entry
|
|
39
|
-
- **WordPress** — `wordpress/ink-editor` classic meta box stub
|
|
54
|
+
## Feature matrix (CK-inspired → Ink 1.1.0)
|
|
40
55
|
|
|
41
|
-
|
|
56
|
+
| Capability | Status |
|
|
57
|
+
|---|---|
|
|
58
|
+
| Classic / document editor shell | **Shipped MVP** |
|
|
59
|
+
| Headings, lists, links, images, colors | **Shipped MVP** |
|
|
60
|
+
| Tables (insert N×M) | **Shipped MVP** |
|
|
61
|
+
| Undo / redo | **Shipped MVP** |
|
|
62
|
+
| Block handles (move up/down) | **Shipped MVP** (full DnD Planned) |
|
|
63
|
+
| Slash commands | **Shipped MVP** |
|
|
64
|
+
| Track changes + Accept/Reject | **Shipped MVP** |
|
|
65
|
+
| Comments archive sidebar | **Shipped MVP** |
|
|
66
|
+
| AI chat + history | **Shipped MVP** (demo provider) |
|
|
67
|
+
| AI Quick Actions / Review / Translate | **Shipped MVP** (demo) |
|
|
68
|
+
| AI diff preview → apply | **Shipped MVP** |
|
|
69
|
+
| Provider registry + model catalog | **Shipped MVP** (catalog constants; BYO run) |
|
|
70
|
+
| Cost control / moderation / permissions / RAG hooks | **Stub** (typed interfaces + no-ops) |
|
|
71
|
+
| Quality eval suite / MCP hosting | **Stub / Planned** |
|
|
72
|
+
| Real-time multiplayer CRDT | **Planned** |
|
|
73
|
+
|
|
74
|
+
## Props (`InkEditorProps`)
|
|
75
|
+
|
|
76
|
+
| Prop | Type | Default | Description |
|
|
77
|
+
|------|------|---------|-------------|
|
|
78
|
+
| `value` / `defaultValue` / `onChange` | HTML string | — | Controlled content |
|
|
79
|
+
| `variant` | `'classic' \| 'document'` | `'classic'` | Shell layout |
|
|
80
|
+
| `features` | `InkFeaturesConfig` | all on | Module toggles |
|
|
81
|
+
| `toolbar` | `ToolbarOption[]` | `INK_DEFAULT_TOOLBAR` | Toolbar controls |
|
|
82
|
+
| `trackChanges` / `onTrackChangesChange` | `InkTrackChange[]` | — | Parallel TC model |
|
|
83
|
+
| `trackChangesEnabled` | `boolean` | `false` | Wrap inserts/deletes |
|
|
84
|
+
| `comments` / `onCommentsChange` | `InkCommentThread[]` | — | Comment threads |
|
|
85
|
+
| `showCommentsPanel` | `boolean` | `false` | Comments archive |
|
|
86
|
+
| `ai` | `InkAiConfig` | — | AI panel config |
|
|
87
|
+
| `slashCommands` | `boolean` | from features | `/` menu |
|
|
88
|
+
| `tableRows` / `tableCols` | `number` | `3` | Default table size |
|
|
89
|
+
| `author` | `string` | `'You'` | TC / comment author |
|
|
90
|
+
| `typoAutoFix` | `boolean` | `true` | Blur typo MVP |
|
|
91
|
+
|
|
92
|
+
## Toolbar options
|
|
42
93
|
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
name: 'My Agent',
|
|
50
|
-
capabilities: ['rewrite'],
|
|
51
|
-
async run({ html }) {
|
|
52
|
-
return { html };
|
|
53
|
-
},
|
|
54
|
-
});
|
|
94
|
+
```
|
|
95
|
+
headingDropdown | bold | italic | underline | strikethrough
|
|
96
|
+
textColor | highlightColor | bulletList | orderedList
|
|
97
|
+
link | image | table | undo | redo
|
|
98
|
+
trackChanges | comments | ai | clearFormat | divider
|
|
99
|
+
+ align* | indent | outdent | blockquote | code | heading1–6
|
|
55
100
|
```
|
|
56
101
|
|
|
57
|
-
|
|
102
|
+
Presets: `INK_DEFAULT_TOOLBAR`, `INK_SIMPLE_TOOLBAR`, `INK_COLLAB_TOOLBAR`.
|
|
103
|
+
|
|
104
|
+
## Ink AI
|
|
58
105
|
|
|
59
106
|
```ts
|
|
60
|
-
import {
|
|
107
|
+
import { inkAi, INK_AI_MODEL_CATALOG } from '@forgedevstack/ink/plugins/ai';
|
|
108
|
+
|
|
109
|
+
// Demo provider is registered by default (no API keys).
|
|
110
|
+
await inkAi.runProvider('demo', {
|
|
111
|
+
capability: 'rewrite',
|
|
112
|
+
html: '<p>Hello</p>',
|
|
113
|
+
selectionHtml: '<p>Hello</p>',
|
|
114
|
+
});
|
|
61
115
|
|
|
62
|
-
|
|
63
|
-
|
|
116
|
+
inkAi.registerProvider({
|
|
117
|
+
id: 'my-openai',
|
|
118
|
+
name: 'My OpenAI',
|
|
119
|
+
models: INK_AI_MODEL_CATALOG.filter((m) => m.provider === 'openai'),
|
|
120
|
+
async run(request) {
|
|
121
|
+
// Call your backend / SDK — Ink does not host models.
|
|
122
|
+
return { html: request.html, text: '…' };
|
|
123
|
+
},
|
|
124
|
+
});
|
|
64
125
|
```
|
|
65
126
|
|
|
66
|
-
|
|
127
|
+
Panel placement: `sidebar` | `drawer` | `floating`. Theme via `ai.uiTheme` / CSS vars `--ink-ai-*`.
|
|
67
128
|
|
|
68
|
-
|
|
129
|
+
Architecture stubs (MVP interfaces): cost-control cache/rate-limit, moderation, permissions, external knowledge, quality eval, fallback chains — see `@forgedevstack/ink/plugins/ai` exports `createNoop*`.
|
|
69
130
|
|
|
70
|
-
|
|
131
|
+
## CSS variables & themes
|
|
71
132
|
|
|
72
|
-
|
|
133
|
+
| Variable | Role |
|
|
134
|
+
|----------|------|
|
|
135
|
+
| `--ink-border` / `--ink-bg` / `--ink-toolbar` | Surfaces |
|
|
136
|
+
| `--ink-text` / `--ink-muted` / `--ink-accent` | Type + accent (teal) |
|
|
137
|
+
| `--ink-shadow` / `--ink-radius` | Card chrome |
|
|
138
|
+
| `--ink-ai-accent` / `--ink-ai-surface` / `--ink-ai-border` | AI panel |
|
|
73
139
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| Companion | https://github.com/yaghobieh/ink-portal |
|
|
140
|
+
Themes: `.ink-theme-snow` · `.ink-theme-bubble` · `.ink-theme-dark` · `.ink-theme-minimal`
|
|
141
|
+
|
|
142
|
+
## Angular / WordPress
|
|
143
|
+
|
|
144
|
+
See `@forgedevstack/ink/angular` and [`wordpress/README.md`](./wordpress/README.md).
|
|
80
145
|
|
|
81
146
|
## License
|
|
82
147
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),f=require("react"),T=require("../../constants/numbers.const.cjs"),u=require("../../constants/defaults.const.cjs"),ee=require("../../utils/cn.utils.cjs"),te=require("../../utils/typo.utils.cjs"),i=require("./helpers/format.utils.cjs"),I=require("./components/ToolbarButton/ToolbarButton.cjs"),re=require("./components/ToolbarDropdown/ToolbarDropdown.cjs"),O=require("./components/ToolbarColorPicker/ToolbarColorPicker.cjs"),b={bold:"B",italic:"I",underline:"U",strikethrough:"S",bulletList:"•",orderedList:"1.",link:"🔗",image:"🖼",clearFormat:"⌫",alignLeft:"⫷",alignCenter:"☰",alignRight:"⫸",alignJustify:"≡",indent:"→",outdent:"←",blockquote:"“",code:"</>"},ne=v=>{const{value:h,defaultValue:_="",onChange:g,placeholder:x=u.INK_PLACEHOLDER_DEFAULT,disabled:n=!1,readOnly:o=!1,minHeight:m=T.INK_MIN_HEIGHT,maxHeight:C,toolbar:y=u.INK_DEFAULT_TOOLBAR,className:E="",testId:S,allowImagePaste:A=!0,showCharCount:L=!1,charCountMax:N,typoAutoFix:B=!0,...F}=v,r=f.useRef(null),[D,U]=f.useState(new Set),[K,k]=f.useState("p"),[j,R]=f.useState(0),[q,w]=f.useState(T.INK_DEFAULT_TEXT_COLOR),[M,P]=f.useState(T.INK_DEFAULT_HIGHLIGHT_COLOR);f.useEffect(()=>{!r.current||h===void 0||r.current.innerHTML!==h&&(r.current.innerHTML=h)},[h]),f.useEffect(()=>{!r.current||h||!_||(r.current.innerHTML=_)},[]);const H=e=>{var t;g==null||g(e),L&&r.current&&R(((t=r.current.textContent)==null?void 0:t.length)??0)},p=()=>{U(i.getActiveFormats());const e=i.queryCommandValue("formatBlock");e&&k(e.toLowerCase().replace(/[<>]/g,""))},d=()=>{r.current&&(H(r.current.innerHTML),p())},V=()=>{if(!r.current||!B||n||o)return;const e=r.current.innerHTML,t=te.applyTypoAutoFix(e);t.html!==e&&(r.current.innerHTML=t.html,H(t.html))},G=e=>{var c;if(n||o)return;(c=r.current)==null||c.focus();const t=u.INK_BUTTON_CONFIG[e];t&&(t.value?i.execCommand(t.command,t.value):i.execCommand(t.command),d())},$=e=>{var t;n||o||((t=r.current)==null||t.focus(),i.execCommand("formatBlock",e),k(e),d())},W=()=>{var t;if(n||o)return;const e=window.prompt("Enter URL:","https://");e&&((t=r.current)==null||t.focus(),i.insertLink(e),d())},J=async()=>{if(n||o)return;const e=document.createElement("input");e.type="file",e.accept="image/*",e.onchange=async()=>{var a,l;const t=(a=e.files)==null?void 0:a[0];if(!t)return;const c=await i.fileToDataUrl(t);(l=r.current)==null||l.focus(),i.insertImage(c,t.name),d()},e.click()},X=async e=>{var c;if(!A||n||o)return;const t=(c=e.clipboardData)==null?void 0:c.items;if(t)for(const a of Array.from(t)){if(!a.type.startsWith("image/"))continue;e.preventDefault();const l=a.getAsFile();if(!l)continue;const Z=await i.fileToDataUrl(l);i.insertImage(Z),d()}},z=(e,t)=>{if(e==="divider")return s.jsx("span",{className:u.INK_CLASS_DIVIDER},`divider-${t}`);if(e==="headingDropdown")return s.jsx(re.ToolbarDropdown,{title:"Heading",options:u.INK_HEADING_OPTIONS,value:K||"p",disabled:n||o,onChange:$},"heading");if(e==="textColor")return s.jsx(O.ToolbarColorPicker,{title:"Text color",type:"text",value:q,disabled:n||o,onChange:a=>{var l;(l=r.current)==null||l.focus(),i.setTextColor(a),w(a),d()}},"textColor");if(e==="highlightColor")return s.jsx(O.ToolbarColorPicker,{title:"Highlight color",type:"highlight",value:M,disabled:n||o,onChange:a=>{var l;(l=r.current)==null||l.focus(),i.setHighlightColor(a),P(a),d()}},"highlightColor");if(e==="link")return s.jsx(I.ToolbarButton,{icon:b.link,title:"Insert link",disabled:n||o,onClick:W},"link");if(e==="image")return s.jsx(I.ToolbarButton,{icon:b.image,title:"Insert image",disabled:n||o,onClick:()=>{J()}},"image");const c=u.INK_BUTTON_CONFIG[e];return c?s.jsx(I.ToolbarButton,{icon:b[e]??e.slice(0,1).toUpperCase(),title:c.title,active:D.has(e),disabled:n||o,onClick:()=>G(e)},e):null},Q=typeof m=="number"?`${m}px`:m,Y=typeof C=="number"?`${C}px`:C;return s.jsxs("div",{className:ee.cn(u.INK_CLASS_ROOT,E),"data-testid":S,"data-disabled":n||void 0,...F,children:[s.jsx("div",{className:u.INK_CLASS_TOOLBAR,role:"toolbar","aria-label":"Ink formatting toolbar",children:y.map(z)}),s.jsx("div",{ref:r,className:u.INK_CLASS_CONTENT,contentEditable:!n&&!o,role:"textbox","aria-multiline":"true","aria-placeholder":x,"data-placeholder":x,suppressContentEditableWarning:!0,style:{minHeight:Q,maxHeight:Y},onInput:d,onBlur:V,onKeyUp:p,onMouseUp:p,onPaste:e=>{X(e)}}),L?s.jsxs("div",{className:u.INK_CLASS_FOOTER,children:[j,N?` / ${N}`:""]}):null]})};exports.InkEditor=ne;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),a=require("react"),J=require("../../constants/numbers.const.cjs"),d=require("../../constants/defaults.const.cjs"),ht=require("../../utils/cn.utils.cjs"),Ct=require("../../utils/typo.utils.cjs"),be=require("../../utils/id.utils.cjs"),gt=require("../../utils/table.utils.cjs"),D=require("../../utils/blocks.utils.cjs"),I=require("../../utils/trackChanges.utils.cjs"),Q=require("../../utils/comments.utils.cjs"),Ie=require("../../utils/history.utils.cjs"),Se=require("../../utils/slash.utils.cjs"),l=require("./helpers/format.utils.cjs"),p=require("./components/ToolbarButton/ToolbarButton.cjs"),pt=require("./components/ToolbarDropdown/ToolbarDropdown.cjs"),xe=require("./components/ToolbarColorPicker/ToolbarColorPicker.cjs"),kt=require("./components/CommentsPanel/CommentsPanel.cjs"),Tt=require("./components/AiPanel/AiPanel.cjs"),bt=require("./components/BlockHandles/BlockHandles.cjs"),It=require("./components/SlashMenu/SlashMenu.cjs"),St=require("./components/TrackChangesBar/TrackChangesBar.cjs"),k={bold:"B",italic:"I",underline:"U",strikethrough:"S",bulletList:"•",orderedList:"1.",link:"🔗",image:"🖼",table:"▦",undo:"↶",redo:"↷",trackChanges:"±",comments:"💬",ai:"✦",clearFormat:"⌫",alignLeft:"⫷",alignCenter:"☰",alignRight:"⫸",alignJustify:"≡",indent:"→",outdent:"←",blockquote:"“",code:"</>"},Y=()=>{const H=window.getSelection();if(!H||H.rangeCount===0)return"";const g=H.getRangeAt(0),S=document.createElement("div");return S.appendChild(g.cloneContents()),S.innerHTML},xt=H=>{var ke;const{value:g,defaultValue:S="",onChange:M,placeholder:Z=d.INK_PLACEHOLDER_DEFAULT,disabled:c=!1,readOnly:i=!1,minHeight:K=J.INK_MIN_HEIGHT,maxHeight:U,toolbar:Le=d.INK_DEFAULT_TOOLBAR,className:_e="",testId:He,allowImagePaste:Ae=!0,showCharCount:ee=!1,charCountMax:te,typoAutoFix:we=!0,variant:Ee=d.INK_DEFAULT_VARIANT,features:Ne,author:x=d.INK_DEFAULT_AUTHOR,trackChanges:A,onTrackChangesChange:q,trackChangesEnabled:y,onTrackChangesEnabledChange:P,comments:w,onCommentsChange:F,showCommentsPanel:E,onShowCommentsPanelChange:V,ai:h,slashCommands:Be,tableRows:ve=d.INK_TABLE_DEFAULT_ROWS,tableCols:ye=d.INK_TABLE_DEFAULT_COLS,...Re}=H,m={...d.INK_DEFAULT_FEATURES,...Ne},o=a.useRef(null),R=a.useRef(new Ie.InkHistoryStack(g??S)),[Oe,je]=a.useState(new Set),[De,ne]=a.useState("p"),[Me,Ke]=a.useState(0),[Ue,qe]=a.useState(J.INK_DEFAULT_TEXT_COLOR),[Pe,Fe]=a.useState(J.INK_DEFAULT_HIGHLIGHT_COLOR),[L,oe]=a.useState(y??!1),[Ve,re]=a.useState(A??[]),[Ge,se]=a.useState(w??[]),[$e,ce]=a.useState(E??!1),[ae,G]=a.useState(!!(h!=null&&h.enabled&&h.openOnInit)),[le,We]=a.useState(""),[Xe,ze]=a.useState(0),[Je,ie]=a.useState(!1),[Qe,O]=a.useState([]),[ue,Ye]=a.useState({top:0,left:0}),T=A??Ve,N=w??Ge,$=E??$e,de=Be??m.slash;a.useEffect(()=>{y!==void 0&&oe(y)},[y]),a.useEffect(()=>{A&&re(A)},[A]),a.useEffect(()=>{w&&se(w)},[w]),a.useEffect(()=>{E!==void 0&&ce(E)},[E]),a.useEffect(()=>{!o.current||g===void 0||o.current.innerHTML!==g&&(o.current.innerHTML=g)},[g]),a.useEffect(()=>{!o.current||g||!S||(o.current.innerHTML=S,R.current=new Ie.InkHistoryStack(S))},[]);const W=e=>{var t;R.current.push(e),M==null||M(e),ee&&o.current&&Ke(((t=o.current.textContent)==null?void 0:t.length)??0)},_=e=>{o.current&&(o.current.innerHTML=e,W(e))},B=e=>{re(e),q==null||q(e)},X=e=>{se(e),F==null||F(e)},z=e=>{ce(e),V==null||V(e)},Ze=e=>{oe(e),P==null||P(e)},j=()=>{je(l.getActiveFormats());const e=l.queryCommandValue("formatBlock");if(e&&ne(e.toLowerCase().replace(/[<>]/g,"")),We(Y()),!o.current||!m.blocks)return;const t=window.getSelection(),n=(t==null?void 0:t.anchorNode)??null,r=D.getBlockElement(n,o.current);if(D.markActiveBlock(o.current,r),r){const u=o.current.getBoundingClientRect(),C=r.getBoundingClientRect();ze(C.top-u.top+o.current.scrollTop),ie(!0)}else ie(!1)},f=()=>{var t,n,r;if(!o.current)return;let e=o.current.innerHTML;if(L&&m.trackChanges){const u=window.getSelection();if(u&&!u.isCollapsed){const C=Y();if(C){const b=I.createTrackChange("delete",C,x);B([...T,b]),et(b.id),e=o.current.innerHTML}}}if(W(e),j(),de&&o.current){const u=((n=(t=window.getSelection())==null?void 0:t.anchorNode)==null?void 0:n.textContent)??"",C=Se.extractSlashQuery(u);if(C!==null){O(Se.filterSlashCommands(C));const b=(r=window.getSelection())==null?void 0:r.getRangeAt(0);if(b&&o.current){const v=b.getBoundingClientRect(),Te=o.current.getBoundingClientRect();Ye({top:v.bottom-Te.top+8,left:v.left-Te.left})}}else O([])}},et=e=>{const t=window.getSelection();if(!t||t.rangeCount===0)return;const n=Y();n&&l.insertHTML(I.wrapDeleteHtml(n,e))},tt=()=>{if(!o.current||!we||!m.typoAutoFix||c||i)return;const e=o.current.innerHTML,t=Ct.applyTypoAutoFix(e);t.html!==e&&(o.current.innerHTML=t.html,W(t.html))},nt=e=>{var n;if(c||i)return;(n=o.current)==null||n.focus();const t=d.INK_BUTTON_CONFIG[e];t&&(t.value?l.execCommand(t.command,t.value):l.execCommand(t.command),f())},ot=e=>{var t;c||i||((t=o.current)==null||t.focus(),l.execCommand("formatBlock",e),ne(e),f())},rt=()=>{var t;if(c||i)return;const e=window.prompt("Enter URL:","https://");e&&((t=o.current)==null||t.focus(),l.insertLink(e),f())},st=async()=>{if(c||i)return;const e=document.createElement("input");e.type="file",e.accept="image/*",e.onchange=async()=>{var r,u;const t=(r=e.files)==null?void 0:r[0];if(!t)return;const n=await l.fileToDataUrl(t);(u=o.current)==null||u.focus(),l.insertImage(n,t.name),f()},e.click()},me=()=>{var t;if(c||i||!m.table)return;(t=o.current)==null||t.focus();const e=gt.buildTableHtml(ve,ye);if(L&&m.trackChanges){const n=I.createTrackChange("insert",e,x);B([...T,n]),l.insertHTML(I.wrapInsertHtml(e,n.id))}else l.insertHTML(e);f()},fe=()=>{const e=R.current.undo();if(e===null||!o.current){l.execCommand("undo"),f();return}_(e)},he=()=>{const e=R.current.redo();if(e===null||!o.current){l.execCommand("redo"),f();return}_(e)},ct=()=>{var u;if(c||i||!m.comments)return;const e=window.prompt("Comment:");if(!(e!=null&&e.trim()))return;const t=be.createInkId("hl");if((u=o.current)==null||u.focus(),!Q.wrapSelectionAsComment(t))return;const r=Q.createCommentThread(x,e.trim(),t);X([r,...N]),z(!0),f()},Ce=e=>{if(!o.current)return;const t=I.acceptTrackChangeInHtml(o.current.innerHTML,e);_(t),B(T.map(n=>n.id===e?{...n,accepted:!0}:n))},ge=e=>{if(!o.current)return;const t=I.rejectTrackChangeInHtml(o.current.innerHTML,e);_(t),B(T.map(n=>n.id===e?{...n,rejected:!0}:n))},at=async e=>{var n;if(!Ae||c||i)return;const t=(n=e.clipboardData)==null?void 0:n.items;if(t)for(const r of Array.from(t)){if(!r.type.startsWith("image/"))continue;e.preventDefault();const u=r.getAsFile();if(!u)continue;const C=await l.fileToDataUrl(u);if(L&&m.trackChanges){const b=`<img src="${C}" alt="" style="max-width:100%;height:auto;" />`,v=I.createTrackChange("insert",b,x);B([...T,v]),l.insertHTML(I.wrapInsertHtml(b,v.id))}else l.insertImage(C);f()}},lt=e=>{e.key==="Escape"&&O([]),(e.metaKey||e.ctrlKey)&&e.key==="z"&&(e.preventDefault(),e.shiftKey?he():fe())},it=e=>{var n,r;(n=o.current)==null||n.focus();const t=window.getSelection();if((r=t==null?void 0:t.anchorNode)!=null&&r.textContent){const C=t.anchorNode.textContent.replace(/(?:^|\s)\/[^\s]*$/," ");t.anchorNode.nodeType===Node.TEXT_NODE&&(t.anchorNode.textContent=C)}switch(O([]),e.insert){case"heading1":l.execCommand("formatBlock","h1");break;case"heading2":l.execCommand("formatBlock","h2");break;case"bulletList":l.execCommand("insertUnorderedList");break;case"orderedList":l.execCommand("insertOrderedList");break;case"table":me();return;case"ai":G(!0);break}f()},pe=e=>{if(!o.current)return;const t=window.getSelection(),n=D.getBlockElement((t==null?void 0:t.anchorNode)??null,o.current);n&&D.moveBlock(n,e)&&(f(),j())},ut=(e,t)=>{if(e==="divider")return s.jsx("span",{className:d.INK_CLASS_DIVIDER},`divider-${t}`);if(e==="headingDropdown")return s.jsx(pt.ToolbarDropdown,{title:"Heading",options:d.INK_HEADING_OPTIONS,value:De||"p",disabled:c||i,onChange:ot},"heading");if(e==="textColor")return s.jsx(xe.ToolbarColorPicker,{title:"Text color",type:"text",value:Ue,disabled:c||i,onChange:r=>{var u;(u=o.current)==null||u.focus(),l.setTextColor(r),qe(r),f()}},"textColor");if(e==="highlightColor")return s.jsx(xe.ToolbarColorPicker,{title:"Highlight color",type:"highlight",value:Pe,disabled:c||i,onChange:r=>{var u;(u=o.current)==null||u.focus(),l.setHighlightColor(r),Fe(r),f()}},"highlightColor");if(e==="link")return s.jsx(p.ToolbarButton,{icon:k.link,title:"Insert link",disabled:c||i,onClick:rt},"link");if(e==="image")return s.jsx(p.ToolbarButton,{icon:k.image,title:"Insert image",disabled:c||i,onClick:()=>{st()}},"image");if(e==="table")return m.table?s.jsx(p.ToolbarButton,{icon:k.table,title:"Insert table",disabled:c||i,onClick:me},"table"):null;if(e==="undo")return s.jsx(p.ToolbarButton,{icon:k.undo,title:"Undo",disabled:c||i,onClick:fe},"undo");if(e==="redo")return s.jsx(p.ToolbarButton,{icon:k.redo,title:"Redo",disabled:c||i,onClick:he},"redo");if(e==="trackChanges")return m.trackChanges?s.jsx(p.ToolbarButton,{icon:k.trackChanges,title:"Track changes",active:L,disabled:c||i,onClick:()=>Ze(!L)},"trackChanges"):null;if(e==="comments")return m.comments?s.jsx(p.ToolbarButton,{icon:k.comments,title:"Comments",active:$,disabled:c||i,onClick:()=>{$?z(!1):ct()}},"comments"):null;if(e==="ai")return!m.ai||!(h!=null&&h.enabled)?null:s.jsx(p.ToolbarButton,{icon:k.ai,title:"Ink AI",active:ae,disabled:c||i,onClick:()=>G(r=>!r)},"ai");const n=d.INK_BUTTON_CONFIG[e];return n?s.jsx(p.ToolbarButton,{icon:k[e]??e.slice(0,1).toUpperCase(),title:n.title,active:Oe.has(e),disabled:c||i,onClick:()=>nt(e)},e):null},dt=typeof K=="number"?`${K}px`:K,mt=typeof U=="number"?`${U}px`:U,ft=!!(h!=null&&h.enabled&&ae);return s.jsxs("div",{className:ht.cn(d.INK_CLASS_ROOT,_e),"data-testid":He,"data-disabled":c||void 0,"data-variant":Ee,...Re,children:[s.jsx("div",{className:d.INK_CLASS_TOOLBAR,role:"toolbar","aria-label":"Ink formatting toolbar",children:Le.map(ut)}),L&&m.trackChanges?s.jsx(St.TrackChangesBar,{changes:T,onAccept:Ce,onReject:ge,onAcceptAll:()=>T.forEach(e=>Ce(e.id)),onRejectAll:()=>T.forEach(e=>ge(e.id))}):null,s.jsxs("div",{className:d.INK_CLASS_SHELL,children:[s.jsxs("div",{className:d.INK_CLASS_BODY,children:[m.blocks?s.jsx(bt.BlockHandles,{visible:Je&&!c&&!i,top:Xe,onMoveUp:()=>pe("up"),onMoveDown:()=>pe("down")}):null,s.jsx("div",{ref:o,className:d.INK_CLASS_CONTENT,contentEditable:!c&&!i,role:"textbox","aria-multiline":"true","aria-placeholder":Z,"data-placeholder":Z,suppressContentEditableWarning:!0,style:{minHeight:dt,maxHeight:mt},onInput:f,onBlur:tt,onKeyUp:j,onKeyDown:lt,onMouseUp:j,onPaste:e=>{at(e)}}),de?s.jsx(It.SlashMenu,{items:Qe,top:ue.top,left:ue.left,onSelect:it}):null]}),$&&m.comments?s.jsx(kt.CommentsPanel,{comments:N,author:x,onClose:()=>z(!1),onResolve:e=>{const t=N.find(n=>n.id===e);X(N.map(n=>n.id===e?{...n,resolved:!0}:n)),t&&o.current&&_(Q.removeCommentMark(o.current.innerHTML,t.highlightId))},onAddReply:(e,t)=>{X(N.map(n=>n.id===e?{...n,replies:[...n.replies,{id:be.createInkId("reply"),author:x,body:t,timestamp:Date.now()}]}:n))}}):null,ft&&h?s.jsx(Tt.AiPanel,{config:h,documentHtml:((ke=o.current)==null?void 0:ke.innerHTML)??g??"",selectionHtml:le,onClose:()=>G(!1),onApplyHtml:e=>{var t;if((t=o.current)==null||t.focus(),le)l.insertHTML(e);else{_(e);return}f()}}):null]}),ee?s.jsxs("div",{className:d.INK_CLASS_FOOTER,children:[Me,te?` / ${te}`:""]}):null]})};exports.InkEditor=xt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkEditor.d.ts","sourceRoot":"","sources":["../../../src/components/InkEditor/InkEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"InkEditor.d.ts","sourceRoot":"","sources":["../../../src/components/InkEditor/InkEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,EAAE,EAIR,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAEV,cAAc,EAIf,MAAM,aAAa,CAAC;AAmGrB,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAyqBxC,CAAC"}
|