Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/data-objects/text-editor/.mocharc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const getFluidTestMochaConfig = require("@fluid-internal/mocha-test-setup/mochar

const config = getFluidTestMochaConfig(__dirname);

// Set up JSDOM before Quill is imported (Quill requires document at import time)
// Run mochaHooks before specs load: registers the CSS loader so `import "quill-next/dist/quill.snow.css"`
// resolves under Node, and installs JSDOM so app.tsx's module load `start()` call has a `document`.
config["node-option"].push("import=./lib/test/mochaHooks.js");

module.exports = config;
2 changes: 1 addition & 1 deletion examples/data-objects/text-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"@fluidframework/test-runtime-utils": "workspace:~",
"@fluidframework/tree": "workspace:~",
"fluid-framework": "workspace:~",
"quill": "^2.0.3",
"quill-next": "^2.2.4",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/data-objects/text-editor/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { FormattedTextAsTree, TextAsTree } from "@fluidframework/tree/internal";
import { SharedTree } from "@fluidframework/tree/legacy";
import type { IFluidContainer } from "fluid-framework";
// eslint-disable-next-line import-x/no-internal-modules, import-x/no-unassigned-import
import "quill/dist/quill.snow.css";
import "quill-next/dist/quill.snow.css";
import { type CSSProperties, type FC, useEffect, useMemo, useState } from "react";
// eslint-disable-next-line import-x/no-internal-modules
import { createRoot } from "react-dom/client";
Expand Down
5 changes: 3 additions & 2 deletions examples/data-objects/text-editor/src/test/mochaHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { register } from "node:module";

import globalJsdom from "global-jsdom";

// Register CSS loader so that CSS imports (e.g. quill/dist/quill.snow.css) resolve to empty modules
// Register CSS loader so that CSS imports (e.g. quill-next/dist/quill.snow.css) resolve to empty modules
register("./cssLoader.js", import.meta.url);

// Set up JSDOM before any modules are loaded (Quill needs document at import time)
// Set up JSDOM before specs load. app.tsx runs `start()` at module-evaluation time, which
// touches `document` — that happens before any test hook can run, so DOM must already exist.
globalJsdom();
5 changes: 0 additions & 5 deletions packages/framework/quill-react/.mocharc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,4 @@ const config = getFluidTestMochaConfig(__dirname);
// AB#7856
config.exit = true;

// Quill accesses `document` at module-import time, so JSDOM must be initialized before any test
// files are loaded. Requiring mochaHooks explicitly here guarantees it runs before spec discovery,
// regardless of alphabetical file-load order within lib/test/.
config.require = [...config.require, "./lib/test/mochaHooks.js"];

module.exports = config;
8 changes: 2 additions & 6 deletions packages/framework/quill-react/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
# @fluidframework/quill-react

Examples for integrating content powered by the Fluid Framework into [React](https://react.dev/) applications that utilize the [Quill](https://quilljs.com/) rich text editor.
Examples for integrating content powered by the Fluid Framework into [React](https://react.dev/) applications that utilize [quill-next](https://www.npmjs.com/package/quill-next), an API-compatible fork of the [Quill](https://quilljs.com/) rich text editor.

This package provides Quill-based views for both plain and formatted text editing backed by SharedTree.

## Known Issues and Limitations

Applications utilizing Quill require DOM access at import time. This package contains all integrations of Fluid Framework with Quill/React. This package should only be imported in browser environments or test environments with JSDOM set up before import.
This package provides quill-next–based views for both plain and formatted text editing backed by SharedTree.

<!-- AUTO-GENERATED-CONTENT:START (LIBRARY_README_HEADER) -->

Expand Down
4 changes: 2 additions & 2 deletions packages/framework/quill-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@
"dependencies": {
"@fluidframework/core-utils": "workspace:~",
"@fluidframework/tree": "workspace:~",
"quill": "^2.0.3",
"quill-delta": "^5.1.0",
"@quill-next/delta-es": "^5.2.12",
"quill-next": "^2.2.4",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import {
} from "@fluidframework/react/internal";
import { TreeAlpha, FormattedTextAsTree } from "@fluidframework/tree/internal";
export { FormattedTextAsTree } from "@fluidframework/tree/internal";
import Quill, { type EmitterSource } from "quill";
import DeltaPackage from "quill-delta";
import DeltaPackage from "@quill-next/delta-es";
import Quill, { type EmitterSource } from "quill-next";
import { type FC, useEffect, useRef, useState } from "react";
import * as ReactDOM from "react-dom";

// Workaround for quill-delta's export style not working well with node16 module resolution.
// Workaround for @quill-next/delta-es's export style not working well with node16 module resolution.
type Delta = DeltaPackage.default;
type QuillDeltaOp = DeltaPackage.Op;
const Delta = DeltaPackage.default;
const Delta = DeltaPackage as unknown as typeof DeltaPackage.default;

/**
* Props for the FormattedMainView component.
Expand Down Expand Up @@ -430,7 +430,7 @@ const FormattedTextEditorView = withMemoizedTreeObservations(
//
// The typing here is very fragile: if no parameter types are given,
// the inference for this event is strongly typed, but the types are wrong (The wrong "Delta" type is provided).
// This is likely related to the node16 module resolution issues with quill-delta.
// This is likely related to the node16 module resolution issues with @quill-next/delta-es.
// If we break that inference by adding types, `any` is inferred for all of them, so incorrect types here would still compile.
const handleTextChange = (
delta: Delta,
Expand Down
2 changes: 1 addition & 1 deletion packages/framework/quill-react/src/plain/quillView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "@fluidframework/react/internal";
import { TreeAlpha } from "@fluidframework/tree/internal";
import type { TextAsTree } from "@fluidframework/tree/internal";
import Quill from "quill";
import Quill from "quill-next";
import { type FC, useEffect, useRef, useState } from "react";
import * as ReactDOM from "react-dom";

Expand Down
2 changes: 1 addition & 1 deletion packages/framework/quill-react/src/test/cleanup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { independentView } from "@fluidframework/tree/alpha";
import { FormattedTextAsTree, TextAsTree } from "@fluidframework/tree/internal";
import { cleanup as rtlCleanup, render } from "@testing-library/react";
import globalJsdom from "global-jsdom";
import Quill from "quill";
import Quill from "quill-next";
import { StrictMode } from "react";

import { FormattedMainView } from "../formatted/index.js";
Expand Down
21 changes: 0 additions & 21 deletions packages/framework/quill-react/src/test/mochaHooks.ts

This file was deleted.

10 changes: 3 additions & 7 deletions packages/framework/quill-react/src/test/textEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { toPropTreeNode, createUndoRedo, type UndoRedo } from "@fluidframework/r
import { TreeViewConfiguration } from "@fluidframework/tree";
import { TreeAlpha, type TreeViewAlpha } from "@fluidframework/tree/alpha";
import { independentView, TextAsTree } from "@fluidframework/tree/internal";
import DeltaPackage from "@quill-next/delta-es";
import { render } from "@testing-library/react";
import globalJsdom from "global-jsdom";
import DeltaPackage from "quill-delta";

import {
clipboardFormatMatcher,
Expand All @@ -29,9 +29,9 @@ import {
// Allow import of files being tested
} from "../plain/index.js";

// Workaround for quill-delta's export style not working well with node16 module resolution.
// See note in quillFormattedView.tsx for why this cast is needed.
type Delta = DeltaPackage.default;
const Delta = DeltaPackage.default;
const Delta = DeltaPackage as unknown as typeof DeltaPackage.default;

// Configuration for creating formatted text views
const formattedTreeConfig = new TreeViewConfiguration({ schema: FormattedTextAsTree.Tree });
Expand Down Expand Up @@ -61,10 +61,6 @@ function createFormattedTreeViewWithEvents(
// TODO add collaboration tests when rich formatting is supported using TestContainerRuntimeFactory from
// @fluidframework/test-utils to test rich formatting data sync between multiple collaborators
describe("textEditor", () => {
// Note: JSDOM is initialized once in mochaHooks.ts before Quill is imported,
// since Quill requires document at import time. See src/test/mochaHooks.ts.
// These tests reset up a clean DOM.

let cleanup: () => void;

// TODO: why does making this beforeEach/afterEach instead of before/after cause cleanup to crash?
Expand Down
2 changes: 1 addition & 1 deletion packages/framework/quill-react/src/test/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"types": ["mocha", "node"],
"noUnusedLocals": false,
},
"include": ["./**/*", "mochaHooks.ts"],
"include": ["./**/*"],
"references": [
{
"path": "../..",
Expand Down
10 changes: 5 additions & 5 deletions packages/framework/quill-react/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
"noUnusedLocals": false,
// ES2021 needed for FinalizationRegistry
"lib": ["ES2021", "DOM", "DOM.Iterable"],
// Suppress type errors in Quill's use of quill-delta.
// Without this, the quill code gives a lot of errors like:
// node_modules/.pnpm/quill@2.0.3/node_modules/quill/blots/block.d.ts:6:17 - error TS2709: Cannot use namespace 'Delta' as a type.
// These issues (and others, see imports of quill-delta) are likely related to quill-delta's export style not working well with node16 module resolution.
// Quill internally uses `"moduleResolution": "bundler"` which seems to work properly with quill-delta's exports, but would be inconsistent with the rest of this repo.
// Suppress type errors in quill-next's use of @quill-next/delta-es.
// Without this, quill-next's .d.ts files give errors like:
// node_modules/.pnpm/quill-next@2.2.4/node_modules/quill-next/blots/block.d.ts:6:17 - error TS2709: Cannot use namespace 'Delta' as a type.
// These issues are related to @quill-next/delta-es's export style not working well with node16 module resolution.
// Quill internally uses `"moduleResolution": "bundler"` which seems to work properly with delta-es's exports, but would be inconsistent with the rest of this repo.
"skipLibCheck": true,
},
}
Loading
Loading