@sofereditor/react 0.2.0 → 0.3.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/dist/index.cjs +1293 -466
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -4
- package/dist/index.d.ts +51 -4
- package/dist/index.js +1239 -393
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
|
-
import { RefObject,
|
|
2
|
-
import { EditorDocument, EditorHistory, SerializedDocument, Selection, MarkName, MarkAttrs, BlockType, BlockAttrs, ListKind, PageSettings, TableLocation, TableRect, ImageEmbed, SerializedBlock, DeltaOp } from '@sofereditor/core';
|
|
1
|
+
import { RefObject, JSX, ReactNode } from 'react';
|
|
2
|
+
import { EditorDocument, EditorHistory, SerializedDocument, Selection, MarkName, MarkAttrs, BlockType, BlockAttrs, AlignValue, ListKind, PageSettings, TableLocation, TableRect, ImageEmbed, EmbedLoc, SerializedBlock, DeltaOp, Position } from '@sofereditor/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Subconjunto mínimo da Awareness do y-protocols que o overlay usa. Tipar assim
|
|
6
|
+
* evita que `@sofereditor/react` dependa de `y-protocols` — o objeto vem de fora
|
|
7
|
+
* (de `useCollab().binding.awareness`) e é estruturalmente compatível.
|
|
8
|
+
*/
|
|
9
|
+
interface AwarenessLike {
|
|
10
|
+
clientID: number;
|
|
11
|
+
getStates(): Map<number, Record<string, unknown>>;
|
|
12
|
+
on(event: "change", cb: () => void): void;
|
|
13
|
+
off(event: "change", cb: () => void): void;
|
|
14
|
+
setLocalStateField(field: string, value: unknown): void;
|
|
15
|
+
}
|
|
16
|
+
interface RemoteCursorsOverlayProps {
|
|
17
|
+
rootRef: RefObject<HTMLDivElement>;
|
|
18
|
+
doc: EditorDocument;
|
|
19
|
+
awareness: AwarenessLike;
|
|
20
|
+
/** Muda a cada edição/repaginação → re-medir os carets remotos. */
|
|
21
|
+
revision?: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Desenha o caret + seleção + nome de cada usuário remoto sobre o conteúdo
|
|
25
|
+
* paginado. Posições remotas chegam via awareness (campo `cursor`, codificado
|
|
26
|
+
* com Y.RelativePosition pelo core) e são resolvidas para coordenadas DOM com
|
|
27
|
+
* o mesmo bridge da seleção local — ciente de fragmentação por página.
|
|
28
|
+
*/
|
|
29
|
+
declare function RemoteCursorsOverlay({ rootRef, doc, awareness, revision, }: RemoteCursorsOverlayProps): JSX.Element | null;
|
|
3
30
|
|
|
4
31
|
/**
|
|
5
32
|
* Sub-phase 3.2 — page layout with intra-paragraph fragmentation.
|
|
@@ -105,6 +132,8 @@ type PendingMarks = Partial<Record<MarkName, MarkAttrs[MarkName] | null>>;
|
|
|
105
132
|
interface LinkRequest {
|
|
106
133
|
initialHref: string;
|
|
107
134
|
resolve: (href: string | null) => void;
|
|
135
|
+
/** Model selection captured when the link was requested (bug #6). */
|
|
136
|
+
selection: Selection;
|
|
108
137
|
}
|
|
109
138
|
interface PageConfigRequest {
|
|
110
139
|
initial: PageSettings;
|
|
@@ -145,6 +174,8 @@ interface UseEditorResult {
|
|
|
145
174
|
getBlockAttr: <K extends keyof BlockAttrs>(key: K) => BlockAttrs[K] | "mixed" | undefined;
|
|
146
175
|
setBlockType: (type: BlockType, attrs?: BlockAttrs) => void;
|
|
147
176
|
setBlockAttr: <K extends keyof BlockAttrs>(key: K, value: BlockAttrs[K] | null) => void;
|
|
177
|
+
setAlign: (value: AlignValue) => void;
|
|
178
|
+
getAlign: () => AlignValue | "mixed" | undefined;
|
|
148
179
|
isListActive: (kind: ListKind) => boolean;
|
|
149
180
|
toggleList: (kind: ListKind) => void;
|
|
150
181
|
indentList: () => void;
|
|
@@ -202,6 +233,11 @@ interface UseEditorResult {
|
|
|
202
233
|
mergeSelection: () => boolean;
|
|
203
234
|
insertImage: (embed: ImageEmbed) => void;
|
|
204
235
|
setImageAttrs: (blockIndex: number, offset: number, partial: Partial<ImageEmbed>, cellIndex?: number, newOffset?: number) => void;
|
|
236
|
+
/**
|
|
237
|
+
* Move a floating image embed from one anchor to another (re-anchor across
|
|
238
|
+
* blocks/pages) in a single transaction. No-op for inline embeds.
|
|
239
|
+
*/
|
|
240
|
+
moveEmbedAnchor: (from: EmbedLoc, to: EmbedLoc, newOffsetX: number, newOffsetY: number) => void;
|
|
205
241
|
/** Read a File (image) and insert it inline at the caret as a data-URL embed. */
|
|
206
242
|
insertImageFromFile: (file: File) => Promise<void>;
|
|
207
243
|
/**
|
|
@@ -244,8 +280,14 @@ interface EditorProps {
|
|
|
244
280
|
* `"<n> / <total>"` centered. Pass `null` to omit.
|
|
245
281
|
*/
|
|
246
282
|
renderPageFooter?: PageRenderProp | null;
|
|
283
|
+
/**
|
|
284
|
+
* Awareness do Yjs (de `useCollab().binding.awareness`). Quando presente,
|
|
285
|
+
* o editor publica a seleção local e desenha os cursores/seleções dos outros
|
|
286
|
+
* usuários (presença colaborativa). Omitir = sem cursores remotos.
|
|
287
|
+
*/
|
|
288
|
+
awareness?: AwarenessLike;
|
|
247
289
|
}
|
|
248
|
-
declare function Editor({ editor: providedEditor, className, pageGeometry, renderPageHeader, renderPageFooter, }: EditorProps): JSX.Element;
|
|
290
|
+
declare function Editor({ editor: providedEditor, className, pageGeometry, renderPageHeader, renderPageFooter, awareness, }: EditorProps): JSX.Element;
|
|
249
291
|
|
|
250
292
|
/**
|
|
251
293
|
* Modal dialog for entering a link URL. Replaces the bare `window.prompt`
|
|
@@ -368,6 +410,11 @@ declare function getCellElement(root: HTMLElement, blockIndex: number, cellIndex
|
|
|
368
410
|
*/
|
|
369
411
|
declare function textOffsetWithin(container: HTMLElement, node: Node, offsetInNode: number): number;
|
|
370
412
|
declare function readDomSelection(root: HTMLElement): Selection | null;
|
|
413
|
+
interface DomPoint {
|
|
414
|
+
node: Node;
|
|
415
|
+
offset: number;
|
|
416
|
+
}
|
|
417
|
+
declare function locatePoint(root: HTMLElement, pos: Position): DomPoint | null;
|
|
371
418
|
declare function selectionsEqual(a: Selection, b: Selection): boolean;
|
|
372
419
|
/**
|
|
373
420
|
* `true` when the selection is a rectangular table-cell range — both endpoints
|
|
@@ -379,4 +426,4 @@ declare function selectionsEqual(a: Selection, b: Selection): boolean;
|
|
|
379
426
|
declare function isTableRectSelection(sel: Selection): boolean;
|
|
380
427
|
declare function applyDomSelection(root: HTMLElement, modelSel: Selection): void;
|
|
381
428
|
|
|
382
|
-
export { A4_PAGE, type BlockFragment, type CaptionAlign, Editor, type EditorProps, EditorProvider, type EditorProviderProps, ImageCaptionDialog, type ImageCaptionRequest, type ImageCaptionResult, LinkDialog, type LinkRequest, NodeView, type NodeViewFragment, PageConfigDialog, type PageConfigRequest, type PageEntry, type PageGeometry, type PageLayout, type PageLayoutResult, type PageRenderContext, type PageRenderProp, type PageSlot, type PaginationPhase, type PendingMarks, type TableRowFragment, Toolbar, type ToolbarProps, type UseEditorOptions, type UseEditorResult, applyDomSelection, contentHeight, contentWidth, defaultPageLayout, deltaLength, findBlockIndex, getBlockElement, getCellElement, getFragmentForOffset, isTableRectSelection, readDomSelection, renderInline, selectionsEqual, sliceDelta, textOffsetWithin, useEditor, useEditorContext, usePageLayout, usePageSettings };
|
|
429
|
+
export { A4_PAGE, type BlockFragment, type CaptionAlign, Editor, type EditorProps, EditorProvider, type EditorProviderProps, ImageCaptionDialog, type ImageCaptionRequest, type ImageCaptionResult, LinkDialog, type LinkRequest, NodeView, type NodeViewFragment, PageConfigDialog, type PageConfigRequest, type PageEntry, type PageGeometry, type PageLayout, type PageLayoutResult, type PageRenderContext, type PageRenderProp, type PageSlot, type PaginationPhase, type PendingMarks, RemoteCursorsOverlay, type TableRowFragment, Toolbar, type ToolbarProps, type UseEditorOptions, type UseEditorResult, applyDomSelection, contentHeight, contentWidth, defaultPageLayout, deltaLength, findBlockIndex, getBlockElement, getCellElement, getFragmentForOffset, isTableRectSelection, locatePoint, readDomSelection, renderInline, selectionsEqual, sliceDelta, textOffsetWithin, useEditor, useEditorContext, usePageLayout, usePageSettings };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
|
-
import { RefObject,
|
|
2
|
-
import { EditorDocument, EditorHistory, SerializedDocument, Selection, MarkName, MarkAttrs, BlockType, BlockAttrs, ListKind, PageSettings, TableLocation, TableRect, ImageEmbed, SerializedBlock, DeltaOp } from '@sofereditor/core';
|
|
1
|
+
import { RefObject, JSX, ReactNode } from 'react';
|
|
2
|
+
import { EditorDocument, EditorHistory, SerializedDocument, Selection, MarkName, MarkAttrs, BlockType, BlockAttrs, AlignValue, ListKind, PageSettings, TableLocation, TableRect, ImageEmbed, EmbedLoc, SerializedBlock, DeltaOp, Position } from '@sofereditor/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Subconjunto mínimo da Awareness do y-protocols que o overlay usa. Tipar assim
|
|
6
|
+
* evita que `@sofereditor/react` dependa de `y-protocols` — o objeto vem de fora
|
|
7
|
+
* (de `useCollab().binding.awareness`) e é estruturalmente compatível.
|
|
8
|
+
*/
|
|
9
|
+
interface AwarenessLike {
|
|
10
|
+
clientID: number;
|
|
11
|
+
getStates(): Map<number, Record<string, unknown>>;
|
|
12
|
+
on(event: "change", cb: () => void): void;
|
|
13
|
+
off(event: "change", cb: () => void): void;
|
|
14
|
+
setLocalStateField(field: string, value: unknown): void;
|
|
15
|
+
}
|
|
16
|
+
interface RemoteCursorsOverlayProps {
|
|
17
|
+
rootRef: RefObject<HTMLDivElement>;
|
|
18
|
+
doc: EditorDocument;
|
|
19
|
+
awareness: AwarenessLike;
|
|
20
|
+
/** Muda a cada edição/repaginação → re-medir os carets remotos. */
|
|
21
|
+
revision?: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Desenha o caret + seleção + nome de cada usuário remoto sobre o conteúdo
|
|
25
|
+
* paginado. Posições remotas chegam via awareness (campo `cursor`, codificado
|
|
26
|
+
* com Y.RelativePosition pelo core) e são resolvidas para coordenadas DOM com
|
|
27
|
+
* o mesmo bridge da seleção local — ciente de fragmentação por página.
|
|
28
|
+
*/
|
|
29
|
+
declare function RemoteCursorsOverlay({ rootRef, doc, awareness, revision, }: RemoteCursorsOverlayProps): JSX.Element | null;
|
|
3
30
|
|
|
4
31
|
/**
|
|
5
32
|
* Sub-phase 3.2 — page layout with intra-paragraph fragmentation.
|
|
@@ -105,6 +132,8 @@ type PendingMarks = Partial<Record<MarkName, MarkAttrs[MarkName] | null>>;
|
|
|
105
132
|
interface LinkRequest {
|
|
106
133
|
initialHref: string;
|
|
107
134
|
resolve: (href: string | null) => void;
|
|
135
|
+
/** Model selection captured when the link was requested (bug #6). */
|
|
136
|
+
selection: Selection;
|
|
108
137
|
}
|
|
109
138
|
interface PageConfigRequest {
|
|
110
139
|
initial: PageSettings;
|
|
@@ -145,6 +174,8 @@ interface UseEditorResult {
|
|
|
145
174
|
getBlockAttr: <K extends keyof BlockAttrs>(key: K) => BlockAttrs[K] | "mixed" | undefined;
|
|
146
175
|
setBlockType: (type: BlockType, attrs?: BlockAttrs) => void;
|
|
147
176
|
setBlockAttr: <K extends keyof BlockAttrs>(key: K, value: BlockAttrs[K] | null) => void;
|
|
177
|
+
setAlign: (value: AlignValue) => void;
|
|
178
|
+
getAlign: () => AlignValue | "mixed" | undefined;
|
|
148
179
|
isListActive: (kind: ListKind) => boolean;
|
|
149
180
|
toggleList: (kind: ListKind) => void;
|
|
150
181
|
indentList: () => void;
|
|
@@ -202,6 +233,11 @@ interface UseEditorResult {
|
|
|
202
233
|
mergeSelection: () => boolean;
|
|
203
234
|
insertImage: (embed: ImageEmbed) => void;
|
|
204
235
|
setImageAttrs: (blockIndex: number, offset: number, partial: Partial<ImageEmbed>, cellIndex?: number, newOffset?: number) => void;
|
|
236
|
+
/**
|
|
237
|
+
* Move a floating image embed from one anchor to another (re-anchor across
|
|
238
|
+
* blocks/pages) in a single transaction. No-op for inline embeds.
|
|
239
|
+
*/
|
|
240
|
+
moveEmbedAnchor: (from: EmbedLoc, to: EmbedLoc, newOffsetX: number, newOffsetY: number) => void;
|
|
205
241
|
/** Read a File (image) and insert it inline at the caret as a data-URL embed. */
|
|
206
242
|
insertImageFromFile: (file: File) => Promise<void>;
|
|
207
243
|
/**
|
|
@@ -244,8 +280,14 @@ interface EditorProps {
|
|
|
244
280
|
* `"<n> / <total>"` centered. Pass `null` to omit.
|
|
245
281
|
*/
|
|
246
282
|
renderPageFooter?: PageRenderProp | null;
|
|
283
|
+
/**
|
|
284
|
+
* Awareness do Yjs (de `useCollab().binding.awareness`). Quando presente,
|
|
285
|
+
* o editor publica a seleção local e desenha os cursores/seleções dos outros
|
|
286
|
+
* usuários (presença colaborativa). Omitir = sem cursores remotos.
|
|
287
|
+
*/
|
|
288
|
+
awareness?: AwarenessLike;
|
|
247
289
|
}
|
|
248
|
-
declare function Editor({ editor: providedEditor, className, pageGeometry, renderPageHeader, renderPageFooter, }: EditorProps): JSX.Element;
|
|
290
|
+
declare function Editor({ editor: providedEditor, className, pageGeometry, renderPageHeader, renderPageFooter, awareness, }: EditorProps): JSX.Element;
|
|
249
291
|
|
|
250
292
|
/**
|
|
251
293
|
* Modal dialog for entering a link URL. Replaces the bare `window.prompt`
|
|
@@ -368,6 +410,11 @@ declare function getCellElement(root: HTMLElement, blockIndex: number, cellIndex
|
|
|
368
410
|
*/
|
|
369
411
|
declare function textOffsetWithin(container: HTMLElement, node: Node, offsetInNode: number): number;
|
|
370
412
|
declare function readDomSelection(root: HTMLElement): Selection | null;
|
|
413
|
+
interface DomPoint {
|
|
414
|
+
node: Node;
|
|
415
|
+
offset: number;
|
|
416
|
+
}
|
|
417
|
+
declare function locatePoint(root: HTMLElement, pos: Position): DomPoint | null;
|
|
371
418
|
declare function selectionsEqual(a: Selection, b: Selection): boolean;
|
|
372
419
|
/**
|
|
373
420
|
* `true` when the selection is a rectangular table-cell range — both endpoints
|
|
@@ -379,4 +426,4 @@ declare function selectionsEqual(a: Selection, b: Selection): boolean;
|
|
|
379
426
|
declare function isTableRectSelection(sel: Selection): boolean;
|
|
380
427
|
declare function applyDomSelection(root: HTMLElement, modelSel: Selection): void;
|
|
381
428
|
|
|
382
|
-
export { A4_PAGE, type BlockFragment, type CaptionAlign, Editor, type EditorProps, EditorProvider, type EditorProviderProps, ImageCaptionDialog, type ImageCaptionRequest, type ImageCaptionResult, LinkDialog, type LinkRequest, NodeView, type NodeViewFragment, PageConfigDialog, type PageConfigRequest, type PageEntry, type PageGeometry, type PageLayout, type PageLayoutResult, type PageRenderContext, type PageRenderProp, type PageSlot, type PaginationPhase, type PendingMarks, type TableRowFragment, Toolbar, type ToolbarProps, type UseEditorOptions, type UseEditorResult, applyDomSelection, contentHeight, contentWidth, defaultPageLayout, deltaLength, findBlockIndex, getBlockElement, getCellElement, getFragmentForOffset, isTableRectSelection, readDomSelection, renderInline, selectionsEqual, sliceDelta, textOffsetWithin, useEditor, useEditorContext, usePageLayout, usePageSettings };
|
|
429
|
+
export { A4_PAGE, type BlockFragment, type CaptionAlign, Editor, type EditorProps, EditorProvider, type EditorProviderProps, ImageCaptionDialog, type ImageCaptionRequest, type ImageCaptionResult, LinkDialog, type LinkRequest, NodeView, type NodeViewFragment, PageConfigDialog, type PageConfigRequest, type PageEntry, type PageGeometry, type PageLayout, type PageLayoutResult, type PageRenderContext, type PageRenderProp, type PageSlot, type PaginationPhase, type PendingMarks, RemoteCursorsOverlay, type TableRowFragment, Toolbar, type ToolbarProps, type UseEditorOptions, type UseEditorResult, applyDomSelection, contentHeight, contentWidth, defaultPageLayout, deltaLength, findBlockIndex, getBlockElement, getCellElement, getFragmentForOffset, isTableRectSelection, locatePoint, readDomSelection, renderInline, selectionsEqual, sliceDelta, textOffsetWithin, useEditor, useEditorContext, usePageLayout, usePageSettings };
|