@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.
Files changed (114) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +103 -38
  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 +515 -16
  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,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
- **ForgeStack rich text editor** for React. WYSIWYG toolbar, heading styles, colors, lists, links, image paste, built-in typo auto-fix MVP, Angular usage stub, and a WordPress plugin stub.
3
+ [![npm version](https://img.shields.io/npm/v/@forgedevstack/ink.svg)](https://www.npmjs.com/package/@forgedevstack/ink)
4
+ [![license](https://img.shields.io/npm/l/@forgedevstack/ink.svg)](./LICENSE)
4
5
 
5
- > **Domain:** [inkforgejs.com](https://inkforgejs.com) placeholder until registered at your registrar.
6
- > Avoid conflating with unrelated brands (e.g. proseforge / forgequill).
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
- 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
26
37
  typoAutoFix
27
38
  />
28
39
  );
29
40
  }
30
41
  ```
31
42
 
32
- ## Features (1.0.0)
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
- - Controlled `value` / `onChange` (HTML string)
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
- ## AI plugin (stub)
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
- ```ts
44
- import { inkAi } from '@forgedevstack/ink/plugins/ai';
45
-
46
- // Register a real agent in 1.x interface is stable now:
47
- inkAi.register({
48
- id: 'my-agent',
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
- ## Angular
102
+ Presets: `INK_DEFAULT_TOOLBAR`, `INK_SIMPLE_TOOLBAR`, `INK_COLLAB_TOOLBAR`.
103
+
104
+ ## Ink AI
58
105
 
59
106
  ```ts
60
- import { createInkAngularUsage, documentInkAngularAdapter } from '@forgedevstack/ink/angular';
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
- console.log(documentInkAngularAdapter());
63
- console.log(createInkAngularUsage());
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
- 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-*`.
67
128
 
68
- ## 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*`.
69
130
 
70
- See [`wordpress/README.md`](./wordpress/README.md).
131
+ ## CSS variables & themes
71
132
 
72
- ## Links
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
- | npm | https://www.npmjs.com/package/@forgedevstack/ink |
77
- | Repo | https://github.com/yaghobieh/ink |
78
- | Portal | https://inkforgejs.com (register domain) |
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,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"}