diff --git a/package-lock.json b/package-lock.json index a89794d4958f..1b23cdd1e574 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29905,6 +29905,28 @@ "typedoc": ">=0.24.0" } }, + "node_modules/typedoc-plugin-rename-defaults": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/typedoc-plugin-rename-defaults/-/typedoc-plugin-rename-defaults-0.7.0.tgz", + "integrity": "sha512-NudSQ1o/XLHNF9c4y7LzIZxfE9ltz09yCDklBPJpP5VMRvuBpYGIbQ0ZgmPz+EIV8vPx9Z/OyKwzp4HT2vDtfg==", + "dependencies": { + "camelcase": "^8.0.0" + }, + "peerDependencies": { + "typedoc": "0.22.x || 0.23.x || 0.24.x || 0.25.x" + } + }, + "node_modules/typedoc-plugin-rename-defaults/node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typedoc/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -33139,6 +33161,7 @@ "react-dom": "^18.2.0", "remark-import-partial": "^0.0.2", "typedoc-plugin-markdown": "^3.17.1", + "typedoc-plugin-rename-defaults": "^0.7.0", "unist-util-visit": "^5.0.0" }, "devDependencies": { @@ -37831,6 +37854,7 @@ "remark-import-partial": "^0.0.2", "tailwindcss": "^3.3.3", "typedoc-plugin-markdown": "^3.17.1", + "typedoc-plugin-rename-defaults": "^0.7.0", "unist-util-visit": "^5.0.0", "webpack": "^5.76.0" } @@ -54579,6 +54603,21 @@ "handlebars": "^4.7.7" } }, + "typedoc-plugin-rename-defaults": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/typedoc-plugin-rename-defaults/-/typedoc-plugin-rename-defaults-0.7.0.tgz", + "integrity": "sha512-NudSQ1o/XLHNF9c4y7LzIZxfE9ltz09yCDklBPJpP5VMRvuBpYGIbQ0ZgmPz+EIV8vPx9Z/OyKwzp4HT2vDtfg==", + "requires": { + "camelcase": "^8.0.0" + }, + "dependencies": { + "camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==" + } + } + }, "typescript": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", diff --git a/packages/lexical-react/src/__tests__/unit/LexicalComposer.test.tsx b/packages/lexical-react/src/__tests__/unit/LexicalComposer.test.tsx index ae9da26b1e83..6896bd0ce481 100644 --- a/packages/lexical-react/src/__tests__/unit/LexicalComposer.test.tsx +++ b/packages/lexical-react/src/__tests__/unit/LexicalComposer.test.tsx @@ -106,6 +106,8 @@ describe('LexicalComposer tests', () => { }); expect(editors.size).toBe(size); [...editors].forEach((editor, i) => { + // This confirms that editorState() was only called once per editor, + // otherwise you could see 'initial stateinitial state'. expect([ i, editor.getEditorState().read(() => $getRoot().getTextContent()), diff --git a/packages/lexical-react/src/useLexicalEditable.ts b/packages/lexical-react/src/useLexicalEditable.ts index d3304616c471..cd799f0c72a6 100644 --- a/packages/lexical-react/src/useLexicalEditable.ts +++ b/packages/lexical-react/src/useLexicalEditable.ts @@ -20,6 +20,14 @@ function subscription(editor: LexicalEditor): LexicalSubscription { }; } +/** + * Get the current value for {@link LexicalEditor.isEditable} + * using {@link useLexicalSubscription}. + * You should prefer this over manually observing the value with + * {@link LexicalEditor.registerEditableListener}, + * which is a bit tricky to do correctly, particularly when using + * React StrictMode (the default for development) or concurrency. + */ export default function useLexicalEditable(): boolean { return useLexicalSubscription(subscription); } diff --git a/packages/lexical-react/src/useLexicalSubscription.tsx b/packages/lexical-react/src/useLexicalSubscription.tsx index c2d88d7b0163..e215f0a8f825 100644 --- a/packages/lexical-react/src/useLexicalSubscription.tsx +++ b/packages/lexical-react/src/useLexicalSubscription.tsx @@ -19,6 +19,7 @@ export type LexicalSubscription = { /** * Shortcut to Lexical subscriptions when values are used for render. + * @param subscription - The function to create the {@link LexicalSubscription}. This function's identity must be stable (e.g. defined at module scope or with useCallback). */ export default function useLexicalSubscription( subscription: (editor: LexicalEditor) => LexicalSubscription, diff --git a/packages/lexical-website/docusaurus.config.js b/packages/lexical-website/docusaurus.config.js index 411091477c20..0d8806821121 100644 --- a/packages/lexical-website/docusaurus.config.js +++ b/packages/lexical-website/docusaurus.config.js @@ -184,6 +184,7 @@ const docusaurusPluginTypedocConfig = { plugin: [ './src/plugins/lexical-typedoc-plugin-no-inherit', './src/plugins/lexical-typedoc-plugin-module-name', + 'typedoc-plugin-rename-defaults', ], sidebar: { autoConfiguration: false, diff --git a/packages/lexical-website/package.json b/packages/lexical-website/package.json index 214e110b1c35..0413f69941c8 100644 --- a/packages/lexical-website/package.json +++ b/packages/lexical-website/package.json @@ -27,6 +27,7 @@ "react-dom": "^18.2.0", "remark-import-partial": "^0.0.2", "typedoc-plugin-markdown": "^3.17.1", + "typedoc-plugin-rename-defaults": "^0.7.0", "unist-util-visit": "^5.0.0" }, "devDependencies": { diff --git a/packages/lexical-website/src/plugins/lexical-typedoc-plugin-module-name/index.js b/packages/lexical-website/src/plugins/lexical-typedoc-plugin-module-name/index.js index 244c5f24b198..199161b2d930 100644 --- a/packages/lexical-website/src/plugins/lexical-typedoc-plugin-module-name/index.js +++ b/packages/lexical-website/src/plugins/lexical-typedoc-plugin-module-name/index.js @@ -5,12 +5,13 @@ * LICENSE file in the root directory of this source tree. * */ +// @ts-check const typedoc = require('typedoc'); -exports.load = function (/** @type typedoc.Application */ app) { +exports.load = function (/** @type {import('typedoc').Application} */ app) { app.converter.on( typedoc.Converter.EVENT_RESOLVE_BEGIN, - (/** @type typedoc.Context */ context) => { + (/** @type {import('typedoc').Context} */ context) => { context.project .getReflectionsByKind(typedoc.ReflectionKind.Module) .forEach((reflection) => {