44 */
55
66import { type PropTreeNode , unwrapPropTreeNode } from "@fluidframework/react/alpha" ;
7- import { Tree } from "@fluidframework/tree" ;
7+ // eslint-disable-next-line import-x/no-internal-modules
8+ import { treeDataObjectInternal } from "@fluidframework/react/internal" ;
9+ import { Tree , TreeViewConfiguration } from "@fluidframework/tree" ;
10+ // eslint-disable-next-line import-x/no-internal-modules
11+ import { FormattedTextAsTree } from "@fluidframework/tree/internal" ;
12+ // eslint-disable-next-line import-x/no-internal-modules
13+ export { FormattedTextAsTree } from "@fluidframework/tree/internal" ;
814import Quill from "quill" ;
915import Delta from "quill-delta" ;
1016import * as React from "react" ;
1117
12- import { FormattedTextAsTree } from "./formattedSchema.js" ;
18+ export const FormattedTextEditorFactory = treeDataObjectInternal (
19+ new TreeViewConfiguration ( { schema : FormattedTextAsTree . Tree } ) ,
20+ ( ) => FormattedTextAsTree . Tree . fromString ( "" ) ,
21+ ) . factory ;
1322
1423/**
1524 * Represents a single operation in a Quill Delta.
1625 * Deltas describe changes to document content as a sequence of operations.
1726 */
1827interface QuillDeltaOp {
19- // Text or embed object to insert at current position
28+ /** Text or embed object to insert at current position. */
2029 insert ?: string | Record < string , unknown > ;
21- // Number of characters to delete at current position
30+ /** Number of characters to delete at current position. */
2231 delete ?: number ;
23- // Number of characters to keep/skip, optionally applying attributes
32+ /** Number of characters to keep/skip, optionally applying attributes. */
2433 retain ?: number ;
25- // Formatting attributes (bold, italic, size, etc.) for insert/retain ops
34+ /** Formatting attributes (bold, italic, size, etc.) for insert/retain ops. */
2635 attributes ?: Record < string , unknown > ;
2736}
2837
29- // Represents a Quill Delta
38+ /** Represents a Quill Delta. */
3039interface QuillDelta {
31- // Sequence of operations that make up this delta
40+ /** Sequence of operations that make up this delta. */
3241 ops ?: QuillDeltaOp [ ] ;
3342}
3443
35- // Props for the FormattedMainView component.
44+ /** Props for the FormattedMainView component. */
3645export interface FormattedMainViewProps {
3746 root : PropTreeNode < FormattedTextAsTree . Tree > ;
3847}
@@ -41,25 +50,25 @@ export const FormattedMainView: React.FC<FormattedMainViewProps> = ({ root }) =>
4150 return < FormattedTextEditorView root = { root } /> ;
4251} ;
4352
44- // Quill size names mapped to pixel values for tree storage
45- const SIZE_MAP : Record < string , number > = { small : 10 , large : 18 , huge : 24 } ;
46- // Reverse mapping: pixel values back to Quill size names for display
47- const SIZE_REVERSE : Record < number , string > = { 10 : "small" , 18 : "large" , 24 : "huge" } ;
48- // Default formatting values when no explicit format is specified
49- const DEFAULT_SIZE = 12 ;
50- const DEFAULT_FONT = "Arial" ;
53+ /** Quill size names mapped to pixel values for tree storage. */
54+ const sizeMap = { small : 10 , large : 18 , huge : 24 } as const ;
55+ /** Reverse mapping: pixel values back to Quill size names for display. */
56+ const sizeReverse = { 10 : "small" , 18 : "large" , 24 : "huge" } as const ;
57+ /** Default formatting values when no explicit format is specified. */
58+ const defaultSize = 12 ;
59+ /** Default font when no explicit font is specified. */
60+ const defaultFont = "Arial" ;
5161
5262/**
5363 * Parse a size value from Quill into a numeric pixel value.
5464 * Handles Quill's named sizes (small, large, huge), numeric values, and pixel strings.
5565 */
5666function parseSize ( size : unknown ) : number {
5767 if ( typeof size === "number" ) return size ;
58- if ( typeof size === "string" ) {
59- // Try named size first, then parse as number, fallback to default
60- return SIZE_MAP [ size ] ?? ( Number . parseInt ( size , 10 ) || DEFAULT_SIZE ) ;
68+ if ( size === "small" || size === "large" || size === "huge" ) {
69+ return sizeMap [ size ] ;
6170 }
62- return DEFAULT_SIZE ;
71+ return defaultSize ;
6372}
6473
6574/**
@@ -79,7 +88,7 @@ function quillAttrsToFormat(attrs?: Record<string, unknown>): {
7988 italic : attrs ?. italic === true ,
8089 underline : attrs ?. underline === true ,
8190 size : parseSize ( attrs ?. size ) ,
82- font : typeof attrs ?. font === "string" ? attrs . font : DEFAULT_FONT ,
91+ font : typeof attrs ?. font === "string" ? attrs . font : defaultFont ,
8392 } ;
8493}
8594
@@ -99,8 +108,7 @@ function quillAttrsToPartial(
99108 if ( "italic" in attrs ) format . italic = attrs . italic === true ;
100109 if ( "underline" in attrs ) format . underline = attrs . underline === true ;
101110 if ( "size" in attrs ) format . size = parseSize ( attrs . size ) ;
102- if ( "font" in attrs )
103- format . font = typeof attrs . font === "string" ? attrs . font : DEFAULT_FONT ;
111+ if ( "font" in attrs ) format . font = typeof attrs . font === "string" ? attrs . font : defaultFont ;
104112 return format ;
105113}
106114
@@ -117,11 +125,11 @@ function formatToQuillAttrs(
117125 if ( format . bold ) attrs . bold = true ;
118126 if ( format . italic ) attrs . italic = true ;
119127 if ( format . underline ) attrs . underline = true ;
120- if ( format . size !== DEFAULT_SIZE ) {
128+ if ( format . size !== defaultSize ) {
121129 // Convert pixel value back to Quill size name if possible
122- attrs . size = SIZE_REVERSE [ format . size ] ?? `${ format . size } px` ;
130+ attrs . size = sizeReverse [ format . size ] ?? `${ format . size } px` ;
123131 }
124- if ( format . font !== DEFAULT_FONT ) attrs . font = format . font ;
132+ if ( format . font !== defaultFont ) attrs . font = format . font ;
125133 return attrs ;
126134}
127135
0 commit comments