@connectedxm/entity-editor 0.0.1 โ†’ 0.0.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Activity Editor
1
+ # Entity Editor
2
2
 
3
- A **zero-dependency**, lightweight React text editor that intelligently recognizes and styles mentions, hashtags, links, and text formatting in real-time using an innovative bitmap-based architecture.
3
+ A **zero-dependency**, lightweight React text editor with intelligent entity recognition and real-time formatting using an innovative bitmap-based architecture.
4
4
 
5
5
  ## โœจ Features
6
6
 
@@ -9,12 +9,13 @@ A **zero-dependency**, lightweight React text editor that intelligently recogniz
9
9
  - **@mentions** (`@username`)
10
10
  - **#interests** (`#hashtag`)
11
11
  - **๐Ÿ”— Links** (`https://example.com`)
12
- - **Text Formatting**: Bold, italic, underline, strikethrough
13
- - **โšก Real-time Processing**: Instant styling as you type with debounced updates
12
+ - **๐Ÿ“ Rich Text Formatting**: Bold, italic, underline, strikethrough with keyboard shortcuts
13
+ - **โšก Real-time Processing**: Instant styling as you type with optimized performance
14
14
  - **๐Ÿ—œ๏ธ Bitmap Architecture**: Ultra-efficient character-level state tracking using bit operations
15
+ - **๐ŸŽจ Customizable Styling**: Configurable colors and styles for all entity types
16
+ - **๐Ÿ” Search & Autocomplete**: Built-in search functionality for mentions and interests
17
+ - **โŒจ๏ธ Keyboard Shortcuts**: Cmd/Ctrl+B/I/U/Shift+S for formatting
15
18
  - **๐Ÿ“ฑ Accessible**: Built on standard `contentEditable` with proper cursor management
16
- - **๐ŸŽจ Customizable**: CSS classes for easy theming
17
- - **โŒจ๏ธ Keyboard Shortcuts**: Cmd/Ctrl+B/I/U/S for formatting selected text
18
19
 
19
20
  ## ๐Ÿ—๏ธ Bitmap Architecture
20
21
 
@@ -58,53 +59,142 @@ npm install @connectedxm/entity-editor
58
59
  ### Basic Usage
59
60
 
60
61
  ```tsx
61
- import React, { useState } from "react";
62
- import Editor from "@connectedxm/entity-editor";
62
+ import React, { useState, useRef } from "react";
63
+ import {
64
+ Editor,
65
+ EditorRef,
66
+ Entity,
67
+ MarkState,
68
+ SearchEntity,
69
+ } from "@connectedxm/entity-editor";
63
70
 
64
71
  function App() {
72
+ const editorRef = useRef<EditorRef>(null);
65
73
  const [plainText, setPlainText] = useState("");
66
- const [entities, setEntities] = useState([]);
67
- const [search, setSearch] = useState(null);
74
+ const [entities, setEntities] = useState<Entity[]>([]);
75
+ const [markState, setMarkState] = useState<MarkState>({
76
+ bold: false,
77
+ italic: false,
78
+ underline: false,
79
+ strike: false,
80
+ });
81
+ const [search, setSearch] = useState<SearchEntity | null>(null);
68
82
 
69
83
  return (
70
84
  <Editor
85
+ ref={editorRef}
71
86
  plainText={plainText}
72
87
  setPlainText={setPlainText}
73
88
  entities={entities}
74
89
  setEntities={setEntities}
90
+ markState={markState}
91
+ setMarkState={setMarkState}
75
92
  search={search}
76
93
  setSearch={setSearch}
77
- options={{ mentions: true, interests: true, links: true }}
78
- style={{ minHeight: "100px", border: "1px solid #ccc", padding: "10px" }}
94
+ options={{
95
+ mentions: true,
96
+ interests: true,
97
+ links: true,
98
+ }}
99
+ style={{
100
+ border: "1px solid #ccc",
101
+ minHeight: "100px",
102
+ padding: "10px",
103
+ }}
79
104
  />
80
105
  );
81
106
  }
82
107
  ```
83
108
 
84
- ### Advanced Features
85
-
86
- The editor supports entity recognition options and debounced updates for performance:
109
+ ### Advanced Usage with Custom Styling
87
110
 
88
111
  ```tsx
89
112
  <Editor
113
+ ref={editorRef}
90
114
  plainText={plainText}
91
115
  setPlainText={setPlainText}
92
116
  entities={entities}
93
117
  setEntities={setEntities}
118
+ markState={markState}
119
+ setMarkState={setMarkState}
94
120
  search={search}
95
121
  setSearch={setSearch}
96
122
  options={{
97
- mentions: true, // Enable @mention detection
98
- interests: true, // Enable #hashtag detection
99
- links: true, // Enable URL detection
123
+ mentions: true,
124
+ interests: true,
125
+ links: true,
126
+ }}
127
+ entityStyles={{
128
+ mentionColor: "#1da1f2",
129
+ interestColor: "#ff6b35",
130
+ linkColor: "#9c27b0",
100
131
  }}
101
- debounceDelay={250} // Delay before processing changes
102
- debounceMaxWait={500} // Maximum wait time for updates
103
132
  className="custom-editor"
133
+ debug={false}
104
134
  />
105
135
  ```
106
136
 
107
- ### Styling Entities
137
+ ### Using the Editor Ref API
138
+
139
+ The editor exposes imperative methods through a ref:
140
+
141
+ ```tsx
142
+ const editorRef = useRef<EditorRef>(null);
143
+
144
+ // Programmatically select/replace entities
145
+ const handleMentionSelect = (username: string) => {
146
+ if (search?.type === "mention") {
147
+ editorRef.current?.selectEntity(
148
+ "mention",
149
+ search.startIndex,
150
+ search.endIndex,
151
+ username
152
+ );
153
+ }
154
+ };
155
+
156
+ // Toggle formatting programmatically
157
+ const makeBold = () => {
158
+ editorRef.current?.toggleMark("bold");
159
+ };
160
+ ```
161
+
162
+ ### Handling Search and Autocomplete
163
+
164
+ ```tsx
165
+ // Handle search results for mentions
166
+ {
167
+ search?.type === "mention" && (
168
+ <div className="autocomplete-dropdown">
169
+ <h4>Select a user to mention:</h4>
170
+ {searchResults.map((user) => (
171
+ <div key={user.id} onClick={() => handleMentionSelect(user.username)}>
172
+ {user.name} (@{user.username})
173
+ </div>
174
+ ))}
175
+ </div>
176
+ );
177
+ }
178
+
179
+ // Handle search results for interests
180
+ {
181
+ search?.type === "interest" && (
182
+ <div className="autocomplete-dropdown">
183
+ <h4>Select an interest to tag:</h4>
184
+ {interestResults.map((interest) => (
185
+ <div
186
+ key={interest.id}
187
+ onClick={() => handleInterestSelect(interest.name)}
188
+ >
189
+ #{interest.name}
190
+ </div>
191
+ ))}
192
+ </div>
193
+ );
194
+ }
195
+ ```
196
+
197
+ ### Styling Entities with CSS
108
198
 
109
199
  Add CSS to style the recognized entities:
110
200
 
@@ -117,34 +207,35 @@ Add CSS to style the recognized entities:
117
207
  }
118
208
 
119
209
  .activity-interest {
120
- color: #1da1f2;
210
+ color: #ff6b35;
121
211
  font-weight: 500;
122
212
  }
123
213
 
124
214
  .activity-link {
125
- color: #1da1f2;
215
+ color: #9c27b0;
126
216
  text-decoration: underline;
127
217
  }
128
218
 
129
219
  .activity-bold {
130
220
  font-weight: bold;
131
221
  }
222
+
132
223
  .activity-italic {
133
224
  font-style: italic;
134
225
  }
226
+
135
227
  .activity-underline {
136
228
  text-decoration: underline;
137
229
  }
230
+
138
231
  .activity-strike {
139
232
  text-decoration: line-through;
140
233
  }
141
234
  ```
142
235
 
143
- ## ๐Ÿ“Š Bitmap to Entity Conversion
144
-
145
- The bitmap system automatically converts character-level bit data into structured entities for easy consumption:
236
+ ## ๐Ÿ“Š Entity Structure
146
237
 
147
- ### Entity Structure
238
+ The editor converts bitmap data into structured entities for easy consumption:
148
239
 
149
240
  ```typescript
150
241
  interface Entity {
@@ -152,49 +243,38 @@ interface Entity {
152
243
  startIndex: number;
153
244
  endIndex: number;
154
245
  marks: ("bold" | "italic" | "underline" | "strike")[];
155
- link?: string; // For detected URLs
156
- mention?: string; // For completed @mentions
157
- interest?: string; // For completed #hashtags
246
+ href?: string; // For links
247
+ username?: string; // For mentions
248
+ interest?: string; // For interests
249
+ }
250
+
251
+ interface SearchEntity {
252
+ type: "mention" | "interest" | "link";
253
+ search: string;
254
+ startIndex: number;
255
+ endIndex: number;
158
256
  }
159
257
  ```
160
258
 
161
- ### Conversion Process
259
+ ### Bitmap to Entity Conversion
162
260
 
163
261
  1. **Bitmap Scanning**: The system scans through the bitmap array
164
262
  2. **Grouping**: Consecutive characters with identical bit values are grouped together
165
263
  3. **Entity Creation**: Each group becomes an entity with its type determined by the bitmap value
166
264
  4. **Mark Extraction**: Formatting bits are converted to a `marks` array
167
265
 
168
- **Example Conversion**:
169
-
170
- ```typescript
171
- // Input bitmap for "Hello @john"
172
- bitmap: [0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 32];
173
-
174
- // Output entities
175
- entities: [
176
- {
177
- type: "mention",
178
- startIndex: 6,
179
- endIndex: 11,
180
- marks: [],
181
- mention: undefined, // Will be filled when mention is resolved
182
- },
183
- ];
184
- ```
185
-
186
266
  ## ๐ŸŽฏ Recognition Patterns
187
267
 
188
268
  - **Mentions**: `@username` (alphanumeric, underscores, hyphens, apostrophes)
189
269
  - **Interests**: `#hashtag` (alphanumeric, underscores, hyphens)
190
270
  - **Links**: `https://` or `http://` URLs
191
- - **Formatting**: Detected from applied HTML styles
271
+ - **Formatting**: Applied via keyboard shortcuts or toolbar
192
272
 
193
273
  ## โšก Performance Benefits
194
274
 
195
275
  ### Why Bitmap Architecture?
196
276
 
197
- The bitmap approach provides significant performance advantages over traditional entity-based systems:
277
+ The bitmap approach provides significant performance advantages:
198
278
 
199
279
  **Memory Efficiency**:
200
280
 
@@ -206,48 +286,81 @@ The bitmap approach provides significant performance advantages over traditional
206
286
 
207
287
  - Bit operations are CPU-native and extremely fast
208
288
  - O(1) property checks vs O(n) object property lookups
209
- - Efficient grouping algorithm for entity generation
210
289
  - **5-10x faster** entity processing
211
290
 
212
291
  **Update Performance**:
213
292
 
214
293
  - Only modified bitmap regions trigger re-rendering
215
- - Debounced updates prevent excessive DOM manipulation
216
- - Minimal React re-renders through optimized state management
294
+ - Optimized React re-renders through efficient state management
217
295
 
218
- ### Benchmark Comparison
296
+ ## ๐Ÿ“ API Reference
219
297
 
220
- ```
221
- Traditional Approach vs Bitmap Approach
222
- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
223
- Memory: 500KB+ Memory: 40KB
224
- Update: 15-30ms Update: 2-5ms
225
- Bundle: +50KB deps Bundle: 0KB deps
226
- ```
298
+ ### Props
227
299
 
228
- ## ๐Ÿ† Why Zero Dependencies?
300
+ | Prop | Type | Required | Description |
301
+ | -------------- | ---------------------------------------- | -------- | ------------------------------------- |
302
+ | `ref` | `React.RefObject<EditorRef>` | Yes | Ref to access editor methods |
303
+ | `plainText` | `string` | Yes | The current plain text content |
304
+ | `setPlainText` | `(text: string) => void` | Yes | Callback to update plain text |
305
+ | `entities` | `Entity[]` | Yes | Array of recognized entities |
306
+ | `setEntities` | `(entities: Entity[]) => void` | Yes | Callback to update entities |
307
+ | `markState` | `MarkState` | Yes | Current formatting state |
308
+ | `setMarkState` | `(state: MarkState) => void` | Yes | Callback to update formatting state |
309
+ | `search` | `SearchEntity \| null` | Yes | Current search state for autocomplete |
310
+ | `setSearch` | `(search: SearchEntity \| null) => void` | Yes | Callback to update search state |
311
+ | `options` | `EntityOptions` | No | Configure which entities to detect |
312
+ | `entityStyles` | `StyleOptions` | No | Custom colors for entity types |
313
+ | `style` | `React.CSSProperties` | No | Inline styles for the editor |
314
+ | `className` | `string` | No | CSS class name for the editor |
315
+ | `debug` | `boolean` | No | Enable debug mode (default: false) |
316
+
317
+ ### Interfaces
229
318
 
230
- This editor proves that powerful text editing doesn't require heavy libraries:
319
+ ```typescript
320
+ interface EntityOptions {
321
+ mentions?: boolean; // Enable @mention detection
322
+ interests?: boolean; // Enable #hashtag detection
323
+ links?: boolean; // Enable URL detection
324
+ }
231
325
 
232
- - **Performance**: No bundle bloat, faster load times
233
- - **Security**: No third-party vulnerabilities
234
- - **Control**: Full understanding and control over every feature
235
- - **Maintenance**: Easier updates and customization
236
- - **Reliability**: No breaking changes from external dependencies
326
+ interface StyleOptions {
327
+ mentionColor?: string; // Custom color for mentions
328
+ interestColor?: string; // Custom color for interests
329
+ linkColor?: string; // Custom color for links
330
+ }
237
331
 
238
- ## ๐Ÿงช Testing
332
+ interface MarkState {
333
+ bold: boolean;
334
+ italic: boolean;
335
+ underline: boolean;
336
+ strike: boolean;
337
+ }
338
+
339
+ interface EditorRef {
340
+ selectEntity: (
341
+ entityType: EntityType,
342
+ startIndex: number,
343
+ endIndex: number,
344
+ newText: string
345
+ ) => void;
346
+ toggleMark: (markType: MarkType) => void;
347
+ }
348
+ ```
349
+
350
+ ### Keyboard Shortcuts
351
+
352
+ - **Ctrl/Cmd + B**: Toggle bold
353
+ - **Ctrl/Cmd + I**: Toggle italic
354
+ - **Ctrl/Cmd + U**: Toggle underline
355
+ - **Ctrl/Cmd + Shift + S**: Toggle strikethrough
239
356
 
240
- The editor includes comprehensive tests covering:
357
+ ## ๐Ÿงช Testing
241
358
 
242
- - **Bitmap Operations**: Bit manipulation, mask operations, value encoding/decoding
243
- - **Entity Conversion**: Bitmap-to-entity transformation accuracy
244
- - **Keyboard Shortcuts**: Formatting toggle functionality via Cmd/Ctrl+B/I/U/S
245
- - **Edge Cases**: Boundary conditions, overlapping entities, empty states
246
- - **Performance**: Large document handling and update efficiency
359
+ Run the test suite:
247
360
 
248
361
  ```bash
249
- npm test # Run all tests
250
- npm run test:run # Run tests once without watch mode
362
+ npm test # Run tests in watch mode
363
+ npm run test:run # Run tests once
251
364
  ```
252
365
 
253
366
  ## ๐Ÿ—๏ธ Development
@@ -262,37 +375,19 @@ npm run dev
262
375
  # Build for production
263
376
  npm run build
264
377
 
265
- # Run tests
266
- npm test
378
+ # Create local package
379
+ npm run local
267
380
  ```
268
381
 
269
- ## ๐Ÿ“ API Reference
270
-
271
- ### Props
382
+ ## ๐Ÿ† Why Zero Dependencies?
272
383
 
273
- | Prop | Type | Default | Description |
274
- | ----------------- | ---------------------------------------- | ------- | ------------------------------------- |
275
- | `plainText` | `string` | - | The current plain text content |
276
- | `setPlainText` | `(text: string) => void` | - | Callback to update plain text |
277
- | `entities` | `Entity[]` | - | Array of recognized entities |
278
- | `setEntities` | `(entities: Entity[]) => void` | - | Callback to update entities |
279
- | `search` | `ActiveEntity \| null` | - | Current search state for autocomplete |
280
- | `setSearch` | `(search: ActiveEntity \| null) => void` | - | Callback to update search state |
281
- | `options` | `EntityOptions` | `{}` | Configure which entities to detect |
282
- | `debounceDelay` | `number` | `250` | Delay before processing changes (ms) |
283
- | `debounceMaxWait` | `number` | `500` | Maximum wait time for updates (ms) |
284
- | `style` | `React.CSSProperties` | - | Optional inline styles |
285
- | `className` | `string` | - | Optional CSS class name |
286
-
287
- ### EntityOptions
384
+ This editor proves that powerful text editing doesn't require heavy libraries:
288
385
 
289
- ```typescript
290
- interface EntityOptions {
291
- mentions?: boolean; // Enable @mention detection
292
- interests?: boolean; // Enable #hashtag detection
293
- links?: boolean; // Enable URL detection
294
- }
295
- ```
386
+ - **Performance**: No bundle bloat, faster load times
387
+ - **Security**: No third-party vulnerabilities
388
+ - **Control**: Full understanding and control over every feature
389
+ - **Maintenance**: Easier updates and customization
390
+ - **Reliability**: No breaking changes from external dependencies
296
391
 
297
392
  ## ๐Ÿค Contributing
298
393
 
@@ -302,16 +397,20 @@ This project maintains its zero-dependency philosophy and bitmap-based architect
302
397
  2. **Bitmap First**: All new features should leverage the bitmap system
303
398
  3. **Performance Focused**: Optimize for memory usage and processing speed
304
399
  4. **TypeScript**: Maintain strict typing throughout
305
- 5. **Test Coverage**: Add comprehensive tests for bitmap operations
400
+ 5. **Test Coverage**: Add comprehensive tests for new features
306
401
  6. **API Stability**: Keep the component interface simple and focused
307
402
 
308
403
  ### Understanding the Codebase
309
404
 
405
+ - `src/Editor.tsx` - Main editor component
406
+ - `src/interfaces.ts` - TypeScript interfaces and types
310
407
  - `src/helpers/bitmap.ts` - Core bitmap manipulation functions
311
408
  - `src/helpers/entities.ts` - Bitmap-to-entity conversion logic
312
409
  - `src/helpers/marks/` - Individual formatting bit operations
313
410
  - `src/helpers/entities/` - Entity type detection and processing
314
411
  - `src/helpers/dom.ts` - DOM manipulation and cursor management
412
+ - `src/helpers/keyboard.ts` - Keyboard shortcut handling
413
+ - `src/hooks/useDebounce.ts` - Debounce hook for performance
315
414
 
316
415
  ## ๐Ÿ“„ License
317
416