@forgedevstack/ink 1.0.1 → 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.
Files changed (114) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +78 -122
  3. package/dist/components/InkEditor/InkEditor.cjs +1 -1
  4. package/dist/components/InkEditor/InkEditor.d.ts.map +1 -1
  5. package/dist/components/InkEditor/InkEditor.js +495 -156
  6. package/dist/components/InkEditor/components/AiPanel/AiPanel.cjs +1 -0
  7. package/dist/components/InkEditor/components/AiPanel/AiPanel.d.ts +11 -0
  8. package/dist/components/InkEditor/components/AiPanel/AiPanel.d.ts.map +1 -0
  9. package/dist/components/InkEditor/components/AiPanel/AiPanel.js +178 -0
  10. package/dist/components/InkEditor/components/AiPanel/index.d.ts +3 -0
  11. package/dist/components/InkEditor/components/AiPanel/index.d.ts.map +1 -0
  12. package/dist/components/InkEditor/components/BlockHandles/BlockHandles.cjs +1 -0
  13. package/dist/components/InkEditor/components/BlockHandles/BlockHandles.d.ts +9 -0
  14. package/dist/components/InkEditor/components/BlockHandles/BlockHandles.d.ts.map +1 -0
  15. package/dist/components/InkEditor/components/BlockHandles/BlockHandles.js +12 -0
  16. package/dist/components/InkEditor/components/BlockHandles/index.d.ts +3 -0
  17. package/dist/components/InkEditor/components/BlockHandles/index.d.ts.map +1 -0
  18. package/dist/components/InkEditor/components/CommentsPanel/CommentsPanel.cjs +1 -0
  19. package/dist/components/InkEditor/components/CommentsPanel/CommentsPanel.d.ts +11 -0
  20. package/dist/components/InkEditor/components/CommentsPanel/CommentsPanel.d.ts.map +1 -0
  21. package/dist/components/InkEditor/components/CommentsPanel/CommentsPanel.js +61 -0
  22. package/dist/components/InkEditor/components/CommentsPanel/index.d.ts +3 -0
  23. package/dist/components/InkEditor/components/CommentsPanel/index.d.ts.map +1 -0
  24. package/dist/components/InkEditor/components/SlashMenu/SlashMenu.cjs +1 -0
  25. package/dist/components/InkEditor/components/SlashMenu/SlashMenu.d.ts +10 -0
  26. package/dist/components/InkEditor/components/SlashMenu/SlashMenu.d.ts.map +1 -0
  27. package/dist/components/InkEditor/components/SlashMenu/SlashMenu.js +20 -0
  28. package/dist/components/InkEditor/components/SlashMenu/index.d.ts +3 -0
  29. package/dist/components/InkEditor/components/SlashMenu/index.d.ts.map +1 -0
  30. package/dist/components/InkEditor/components/TrackChangesBar/TrackChangesBar.cjs +1 -0
  31. package/dist/components/InkEditor/components/TrackChangesBar/TrackChangesBar.d.ts +11 -0
  32. package/dist/components/InkEditor/components/TrackChangesBar/TrackChangesBar.d.ts.map +1 -0
  33. package/dist/components/InkEditor/components/TrackChangesBar/TrackChangesBar.js +27 -0
  34. package/dist/components/InkEditor/components/TrackChangesBar/index.d.ts +3 -0
  35. package/dist/components/InkEditor/components/TrackChangesBar/index.d.ts.map +1 -0
  36. package/dist/components/InkEditor/components/index.d.ts +5 -0
  37. package/dist/components/InkEditor/components/index.d.ts.map +1 -1
  38. package/dist/constants/aiModels.const.cjs +1 -0
  39. package/dist/constants/aiModels.const.d.ts +5 -0
  40. package/dist/constants/aiModels.const.d.ts.map +1 -0
  41. package/dist/constants/aiModels.const.js +31 -0
  42. package/dist/constants/defaults.const.cjs +1 -1
  43. package/dist/constants/defaults.const.d.ts +32 -1
  44. package/dist/constants/defaults.const.d.ts.map +1 -1
  45. package/dist/constants/defaults.const.js +124 -20
  46. package/dist/constants/index.d.ts +1 -0
  47. package/dist/constants/index.d.ts.map +1 -1
  48. package/dist/constants/numbers.const.cjs +1 -1
  49. package/dist/constants/numbers.const.d.ts +13 -0
  50. package/dist/constants/numbers.const.d.ts.map +1 -1
  51. package/dist/constants/numbers.const.js +13 -3
  52. package/dist/index.cjs +1 -1
  53. package/dist/index.d.ts +3 -3
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +32 -13
  56. package/dist/plugins/ai/aiPlugin.cjs +1 -1
  57. package/dist/plugins/ai/aiPlugin.d.ts.map +1 -1
  58. package/dist/plugins/ai/aiPlugin.js +40 -18
  59. package/dist/plugins/ai/demoProvider.cjs +1 -0
  60. package/dist/plugins/ai/demoProvider.d.ts +3 -0
  61. package/dist/plugins/ai/demoProvider.d.ts.map +1 -0
  62. package/dist/plugins/ai/demoProvider.js +130 -0
  63. package/dist/plugins/ai/index.cjs +1 -1
  64. package/dist/plugins/ai/index.d.ts +4 -1
  65. package/dist/plugins/ai/index.d.ts.map +1 -1
  66. package/dist/plugins/ai/index.js +15 -3
  67. package/dist/plugins/ai/stubs.cjs +1 -0
  68. package/dist/plugins/ai/stubs.d.ts +7 -0
  69. package/dist/plugins/ai/stubs.d.ts.map +1 -0
  70. package/dist/plugins/ai/stubs.js +23 -0
  71. package/dist/styles.css +464 -19
  72. package/dist/types/ai.types.d.ts +111 -2
  73. package/dist/types/ai.types.d.ts.map +1 -1
  74. package/dist/types/comments.types.d.ts +17 -0
  75. package/dist/types/comments.types.d.ts.map +1 -0
  76. package/dist/types/features.types.d.ts +5 -0
  77. package/dist/types/features.types.d.ts.map +1 -0
  78. package/dist/types/index.d.ts +5 -2
  79. package/dist/types/index.d.ts.map +1 -1
  80. package/dist/types/ink.types.d.ts +26 -1
  81. package/dist/types/ink.types.d.ts.map +1 -1
  82. package/dist/types/trackChanges.types.d.ts +12 -0
  83. package/dist/types/trackChanges.types.d.ts.map +1 -0
  84. package/dist/utils/blocks.utils.cjs +1 -0
  85. package/dist/utils/blocks.utils.d.ts +4 -0
  86. package/dist/utils/blocks.utils.d.ts.map +1 -0
  87. package/dist/utils/blocks.utils.js +41 -0
  88. package/dist/utils/comments.utils.cjs +1 -0
  89. package/dist/utils/comments.utils.d.ts +5 -0
  90. package/dist/utils/comments.utils.d.ts.map +1 -0
  91. package/dist/utils/comments.utils.js +32 -0
  92. package/dist/utils/history.utils.cjs +1 -0
  93. package/dist/utils/history.utils.d.ts +13 -0
  94. package/dist/utils/history.utils.d.ts.map +1 -0
  95. package/dist/utils/history.utils.js +29 -0
  96. package/dist/utils/id.utils.cjs +1 -0
  97. package/dist/utils/id.utils.d.ts +2 -0
  98. package/dist/utils/id.utils.d.ts.map +1 -0
  99. package/dist/utils/id.utils.js +4 -0
  100. package/dist/utils/index.d.ts +7 -0
  101. package/dist/utils/index.d.ts.map +1 -1
  102. package/dist/utils/slash.utils.cjs +1 -0
  103. package/dist/utils/slash.utils.d.ts +4 -0
  104. package/dist/utils/slash.utils.d.ts.map +1 -0
  105. package/dist/utils/slash.utils.js +13 -0
  106. package/dist/utils/table.utils.cjs +1 -0
  107. package/dist/utils/table.utils.d.ts +2 -0
  108. package/dist/utils/table.utils.d.ts.map +1 -0
  109. package/dist/utils/table.utils.js +13 -0
  110. package/dist/utils/trackChanges.utils.cjs +1 -0
  111. package/dist/utils/trackChanges.utils.d.ts +7 -0
  112. package/dist/utils/trackChanges.utils.d.ts.map +1 -0
  113. package/dist/utils/trackChanges.utils.js +34 -0
  114. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
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
+
3
28
  ## 1.0.1 — 2026-08-01
4
29
 
5
30
  ### Added
package/README.md CHANGED
@@ -3,14 +3,15 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@forgedevstack/ink.svg)](https://www.npmjs.com/package/@forgedevstack/ink)
4
4
  [![license](https://img.shields.io/npm/l/@forgedevstack/ink.svg)](./LICENSE)
5
5
 
6
- **ForgeStack rich text editor** for React. WYSIWYG toolbar, heading styles, colors, lists, links, image paste, built-in typo auto-fix MVP, CSS themes, Angular usage stub, and a WordPress plugin stub.
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
7
 
8
8
  <p align="center">
9
9
  <img src="./assets/ink-logo.png" alt="Ink logo" width="120" />
10
10
  </p>
11
11
 
12
- > **Domain:** [inkforgejs.com](https://inkforgejs.com) — docs + playground.
13
- > **Inspired by Quill** in UX (light paper UI, docs sidebar, Format/Modules/Theme playground) — not a Quill fork. Ink is a contenteditable React component with ForgeStack integrations.
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`.
14
15
 
15
16
  ## Install
16
17
 
@@ -29,7 +30,10 @@ export function App() {
29
30
  <InkEditor
30
31
  value={value}
31
32
  onChange={setValue}
32
- placeholder="Write something…"
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
33
37
  typoAutoFix
34
38
  />
35
39
  );
@@ -41,151 +45,103 @@ export function App() {
41
45
  | | |
42
46
  |---|---|
43
47
  | Docs portal | [ink-portal](https://github.com/yaghobieh/ink-portal) · [inkforgejs.com](https://inkforgejs.com) |
44
- | Live playground | `/playground` — Formats, Modules, Theme + code export |
48
+ | Demos hub | `/demos` |
49
+ | Ink AI | `/ai` |
50
+ | Live playground | `/playground` |
45
51
  | npm | https://www.npmjs.com/package/@forgedevstack/ink |
46
52
  | Repo | https://github.com/yaghobieh/ink |
47
53
 
48
- <p align="center">
49
- <img src="./assets/ink-hero.png" alt="Ink hero" width="640" />
50
- </p>
54
+ ## Feature matrix (CK-inspired → Ink 1.1.0)
55
+
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** |
51
73
 
52
74
  ## Props (`InkEditorProps`)
53
75
 
54
76
  | Prop | Type | Default | Description |
55
77
  |------|------|---------|-------------|
56
- | `value` | `string` | — | Controlled HTML |
57
- | `defaultValue` | `string` | | Uncontrolled initial HTML |
58
- | `onChange` | `(html: string) => void` | | Fires when content changes |
59
- | `placeholder` | `string` | `"Start typing..."` | Empty-state placeholder |
60
- | `disabled` | `boolean` | `false` | Disables interaction |
61
- | `readOnly` | `boolean` | `false` | View-only content |
62
- | `minHeight` | `string \| number` | — | Content min height |
63
- | `maxHeight` | `string \| number` | | Content max height |
64
- | `toolbar` | `ToolbarOption[]` | `INK_DEFAULT_TOOLBAR` | Toolbar buttons / controls |
65
- | `testId` | `string` | | Testing id |
66
- | `allowImagePaste` | `boolean` | `true` | Paste images into the editor |
67
- | `showCharCount` | `boolean` | `false` | Footer character count |
68
- | `charCountMax` | `number` | | Optional max for counter UI |
69
- | `typoAutoFix` | `boolean` | `false` | Blur-time typo MVP fixes |
70
-
71
- Also accepts standard `div` HTML attributes except `onChange`.
72
-
73
- ## Toolbar options (`ToolbarOption`)
74
-
75
- ```
76
- bold | italic | underline | strikethrough
77
- heading1 | heading2 | heading3 | heading4 | heading5 | heading6
78
- paragraph | headingDropdown
79
- bulletList | orderedList | blockquote | code
80
- link | image | textColor | highlightColor
81
- alignLeft | alignCenter | alignRight | alignJustify
82
- indent | outdent | clearFormat | divider
83
- ```
84
-
85
- Presets exported from the package:
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
86
93
 
87
- - `INK_DEFAULT_TOOLBAR` — full editing set
88
- - `INK_SIMPLE_TOOLBAR` — bold / italic / underline + lists
89
-
90
- ```tsx
91
- import { InkEditor, INK_SIMPLE_TOOLBAR } from '@forgedevstack/ink';
92
-
93
- <InkEditor toolbar={INK_SIMPLE_TOOLBAR} />
94
94
  ```
95
-
96
- ## CSS variables & themes
97
-
98
- Root class: `.Ink-Editor`. Override variables on a wrapper or the editor:
99
-
100
- | Variable | Role |
101
- |----------|------|
102
- | `--ink-border` | Borders |
103
- | `--ink-bg` | Editor background |
104
- | `--ink-toolbar` | Toolbar background |
105
- | `--ink-text` | Body text |
106
- | `--ink-muted` | Placeholder / footer |
107
- | `--ink-accent` | Active / accent |
108
- | `--ink-accent-soft` | Active button soft fill |
109
-
110
- Theme helper classes (wrap the editor or add to the root):
111
-
112
- | Class | Look |
113
- |-------|------|
114
- | `.ink-theme-snow` | Clean Quill-like paper toolbar |
115
- | `.ink-theme-bubble` | Soft floating card |
116
- | `.ink-theme-dark` | Dark zinc surfaces |
117
- | `.ink-theme-minimal` | Flat, dashed toolbar edge |
118
-
119
- ```tsx
120
- <div className="ink-theme-snow">
121
- <InkEditor value={html} onChange={setHtml} />
122
- </div>
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
123
100
  ```
124
101
 
125
- ## Modules
102
+ Presets: `INK_DEFAULT_TOOLBAR`, `INK_SIMPLE_TOOLBAR`, `INK_COLLAB_TOOLBAR`.
126
103
 
127
- - **Typo auto-fix** — `typoAutoFix` runs `applyTypoAutoFix` on blur (small bundled dictionary; not a full spell engine)
128
- - **Image paste** — `allowImagePaste`
129
- - **Char count** — `showCharCount` / `charCountMax`
130
- - **Read only** — `readOnly`
104
+ ## Ink AI
131
105
 
132
106
  ```ts
133
- import { applyTypoAutoFix } from '@forgedevstack/ink';
134
-
135
- const { html, fixedCount } = applyTypoAutoFix(rawHtml);
136
- ```
107
+ import { inkAi, INK_AI_MODEL_CATALOG } from '@forgedevstack/ink/plugins/ai';
137
108
 
138
- ## AI plugin (stub)
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
+ });
139
115
 
140
- ```ts
141
- import { inkAi } from '@forgedevstack/ink/plugins/ai';
142
-
143
- inkAi.register({
144
- id: 'my-agent',
145
- name: 'My Agent',
146
- capabilities: ['rewrite'],
147
- async run({ html }) {
148
- return { html };
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: '' };
149
123
  },
150
124
  });
151
125
  ```
152
126
 
153
- Full agents land in **1.x**.
154
-
155
- ## Angular
156
-
157
- ```ts
158
- import { createInkAngularUsage, documentInkAngularAdapter } from '@forgedevstack/ink/angular';
159
-
160
- console.log(documentInkAngularAdapter());
161
- console.log(createInkAngularUsage());
162
- ```
163
-
164
- Mount `InkEditor` via your preferred React↔Angular bridge. A dedicated Angular component lands in 1.x.
127
+ Panel placement: `sidebar` | `drawer` | `floating`. Theme via `ai.uiTheme` / CSS vars `--ink-ai-*`.
165
128
 
166
- ## WordPress
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*`.
167
130
 
168
- See [`wordpress/README.md`](./wordpress/README.md).
131
+ ## CSS variables & themes
169
132
 
170
- ## Positioning vs Quill
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 |
171
139
 
172
- | | Quill | Ink |
173
- |---|---|---|
174
- | Core | Delta document model + Parchment | HTML string + contenteditable |
175
- | Framework | Framework-agnostic | React-first (ForgeStack) |
176
- | Themes | Snow / Bubble built-in | CSS variables + `ink-theme-*` classes |
177
- | Typo / AI | Ecosystem plugins | Built-in typo MVP + AI register stub |
178
- | License / lineage | Quill open source | Independent MIT package — **inspired by**, not a fork |
140
+ Themes: `.ink-theme-snow` · `.ink-theme-bubble` · `.ink-theme-dark` · `.ink-theme-minimal`
179
141
 
180
- ## Features (1.0.1)
142
+ ## Angular / WordPress
181
143
 
182
- - Controlled `value` / `onChange` (HTML string)
183
- - Toolbar: bold / italic / underline / strike, headings, text + highlight colors, lists, links, image insert/paste
184
- - **Typo auto-fix MVP** — bundled dictionary + heuristics
185
- - **Theme classes** — snow / bubble / dark / minimal
186
- - **AI agent stub** — `@forgedevstack/ink/plugins/ai`
187
- - **Angular** — `@forgedevstack/ink/angular` helpers
188
- - **WordPress** — `wordpress/ink-editor` stub
144
+ See `@forgedevstack/ink/angular` and [`wordpress/README.md`](./wordpress/README.md).
189
145
 
190
146
  ## License
191
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,EAA+B,KAAK,EAAE,EAAuC,MAAM,OAAO,CAAC;AAClG,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAgDjE,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAiQxC,CAAC"}
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"}