Skip to content

TypeScript: Migrate format-library package to TS - #79486

Merged
im3dabasia merged 49 commits into
WordPress:trunkfrom
im3dabasia:try/migrate-format-library-package
Sep 2, 2026
Merged

im3dabasia merged 49 commits into
WordPress:trunkfrom
im3dabasia:try/migrate-format-library-package

Conversation

@im3dabasia

@im3dabasia im3dabasia commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

What?

Part of: #67691
Migrating the format-library package to Typescript.

Why?

Type safety.

Behaviour changes

Typing surfaced a few latent issues. These are behaviour changes, not typing:

  • Bold and italic now announce apply/remove to screen readers, matching every other format.
  • Highlight: a colour without a slug falls back to inline style instead of an empty class.
  • Inline image: clearing alt text now writes an empty attribute rather than leaving it undefined.
  • Link: an empty URL becomes an empty string, not undefined, before validation.
  • Link: editing a link with no selection bails out instead of throwing.

Notes on review feedback

  • replace() accepted a value object at runtime but declared {Function|string}; corrected in rich-text.
  • The block-editor tsconfig reference stays — validate-tsconfig requires one per @wordpress/* dependency.

@github-actions github-actions Bot added [Package] Format library /packages/format-library [Package] Rich text /packages/rich-text labels Jun 24, 2026
@im3dabasia
im3dabasia requested a review from Copilot June 30, 2026 04:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request migrates the @wordpress/format-library package source to TypeScript/TSX and updates @wordpress/rich-text typing/exports to support the migration, as part of the broader TypeScript conversion effort tracked in #67691.

Changes:

  • Add TypeScript project configuration and project references for packages/format-library.
  • Convert format implementations in format-library to TS/TSX with explicit prop/value typing and safer interop typings.
  • Expand and re-export RichTextFormat typing from @wordpress/rich-text, plus related documentation updates.

Reviewed changes

Copilot reviewed 26 out of 30 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tsconfig.json Adds packages/format-library to TS project references.
packages/rich-text/src/types.ts Extends RichTextFormat shape (title/attributes/innerHTML) for TS consumers.
packages/rich-text/src/register-format-type.js Updates typedef docs to reflect TS-friendly format settings shape.
packages/rich-text/src/index.ts Re-exports RichTextFormat from ./types.
packages/rich-text/README.md Adds a section documenting RichTextFormat.
packages/format-library/tsconfig.json Introduces TS config + references for the format-library workspace.
packages/format-library/src/index.tsx Adds a TS entrypoint to register default formats.
packages/format-library/src/default-formats.tsx Centralizes the list of exported default formats.
packages/format-library/src/types.ts Adds shared TS prop types for multiple format edit UIs.
packages/format-library/src/lock-unlock.ts Adds a typed wrapper for private-apis lock/unlock usage.
packages/format-library/src/bold/index.tsx Converts bold format implementation to TSX and typed props.
packages/format-library/src/italic/index.tsx Converts italic format implementation to TSX and typed props.
packages/format-library/src/code/index.tsx Converts code format implementation to TSX and types the input rule/edit props.
packages/format-library/src/underline/index.tsx Converts underline edit props to typed TSX.
packages/format-library/src/strikethrough/index.tsx Converts strikethrough edit props and toolbar button usage to TSX.
packages/format-library/src/subscript/index.tsx Converts subscript edit props and toolbar button usage to TSX.
packages/format-library/src/superscript/index.tsx Converts superscript edit props and toolbar button usage to TSX.
packages/format-library/src/keyboard/index.tsx Converts keyboard format edit props to typed TSX.
packages/format-library/src/non-breaking-space/index.tsx Adds explicit TS props for non-breaking-space edit.
packages/format-library/src/unknown/index.tsx Adds RichTextValue typing and TS interop for toolbar button component typing.
packages/format-library/src/language/index.tsx Converts language format to TSX with typed props and anchor typing.
packages/format-library/src/math/index.tsx Converts math format UI to TSX with typed props/state.
packages/format-library/src/image/index.tsx Converts inline image format UI to TSX with typed attributes/selection handling.
packages/format-library/src/text-color/index.tsx Converts text-color format UI to TSX with typed props and safer DOM access.
packages/format-library/src/text-color/inline.tsx Converts InlineColorUI helpers/components to TSX with explicit color/value typing.
packages/format-library/src/link/index.tsx Converts link format edit UI to TSX with typed state and event handling.
packages/format-library/src/link/inline.tsx Converts inline link UI to TSX with typed link value + safer rich-text operations typing.
packages/format-library/src/link/utils.ts Adds TS types for link utilities (href validation, link format creation, boundary helpers).
packages/format-library/src/link/use-link-instance-key.ts Types the link instance key helper hook.
packages/format-library/src/link/css-classes-setting.tsx Types CSS classes setting component props and sanitization handler.
Comments suppressed due to low confidence (3)

packages/rich-text/src/types.ts:11

  • RichTextFormat includes the literal 'core/link ' with a trailing space, which is easy to miss and will cause inconsistent type matching if | string is ever narrowed later.
	innerHTML?: string;
	type:
		| 'core/bold'
		| 'core/italic'
		| 'core/link '

packages/format-library/src/math/index.tsx:48

  • EditProps is declared twice in this file, which will fail TypeScript compilation due to a duplicate identifier.
    packages/format-library/src/link/utils.ts:168
  • The JSDoc still describes format as a string identifier, but the function now expects a format object with a type field; please update the doc to match the actual parameter type.

@im3dabasia im3dabasia added the [Type] Code Quality Issues or PRs that relate to code quality label Jun 30, 2026
@im3dabasia
im3dabasia requested a review from manzoorwanijk June 30, 2026 05:52
@im3dabasia
im3dabasia force-pushed the try/migrate-format-library-package branch from cc81a16 to 36eb047 Compare June 30, 2026 06:00
@manzoorwanijk

Copy link
Copy Markdown
Member

Let us first make the CI happy before we can review this.

@github-actions github-actions Bot added the [Package] Block editor /packages/block-editor label Jun 30, 2026
@im3dabasia

Copy link
Copy Markdown
Contributor Author

@manzoorwanijk , CI is now happy 😂 , Please help me with the review! Over to you! TIA 🙇

@im3dabasia
im3dabasia marked this pull request as ready for review June 30, 2026 10:24
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: im3dabasia <im3dabasia1@git.wordpress.org>
Co-authored-by: manzoorwanijk <manzoorwanijk@git.wordpress.org>
Co-authored-by: aduth <aduth@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@manzoorwanijk
manzoorwanijk requested a review from Copilot June 30, 2026 10:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@im3dabasia

Copy link
Copy Markdown
Contributor Author

I think you've hit your monthly quota, so I'll take care of it for you.

@manzoorwanijk manzoorwanijk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this makes me realize that we should first convert the dependency packages like block-editor to avoid too many suppressions and use of any.

Comment thread packages/format-library/src/bold/index.tsx Outdated
Comment thread packages/format-library/src/bold/index.tsx Outdated
Comment thread packages/format-library/src/code/index.tsx Outdated
Comment thread packages/format-library/src/image/index.tsx Outdated
Comment thread packages/format-library/src/italic/index.tsx Outdated
Comment thread packages/format-library/src/link/inline.tsx Outdated
Comment thread packages/format-library/src/link/inline.tsx Outdated
Comment thread packages/format-library/src/math/index.tsx Outdated
Comment thread packages/format-library/src/non-breaking-space/index.tsx Outdated
Comment thread packages/format-library/src/strikethrough/index.tsx Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 31 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

packages/format-library/src/link/inline.tsx:220

  • splitValue ?? [] allows valAfter to become undefined, but replace(valAfter, …) will then throw at runtime; either assert split always returns a tuple here or handle the undefined case explicitly.

Comment thread packages/rich-text/README.md
Comment thread tools/eslint/suppressions.json
Comment thread packages/format-library/src/link/inline.tsx Outdated
Comment thread packages/format-library/src/link/inline.tsx Outdated
Comment thread packages/format-library/src/link/inline.tsx Outdated
Comment thread packages/format-library/src/link/inline.tsx Outdated
Comment thread packages/format-library/src/link/inline.tsx Outdated
Comment thread packages/format-library/src/types.ts
Comment thread packages/format-library/src/link/utils.ts
Comment thread packages/format-library/src/link/utils.ts Outdated
Comment thread packages/format-library/tsconfig.json
Comment thread packages/format-library/src/link/css-classes-setting.tsx Outdated
@manzoorwanijk

Copy link
Copy Markdown
Member

Checked out locally on a clean install: tsc -b packages/format-library is clean, lint:js is clean, the 30 package unit tests pass, and docs:build produces no diff. Thanks for working through this one, it's a big surface.

The migration is broadly sound. Three things outside the diff, plus one regression and a set of unnecessary casts inline.

Not visible in the diff:

  1. packages/format-library/package.json is missing "types": "build-types/index.d.ts" and exports["."].types. build-types is already in files, but nothing points at it, so consumers get no types. Compare packages/server-side-render or packages/rich-text.
  2. No CHANGELOG entries. packages/rich-text/CHANGELOG.md needs one for the new public RichTextFormat export, and packages/format-library/CHANGELOG.md an Internal entry.
  3. src/index.tsx and src/default-formats.tsx contain no JSX and should be .ts.

One regression: link/inline.tsx now coerces an undefined format boundary to 0, which changes where the value is split. Details inline.

Runtime changes that aren't type-driven: title added to the format objects in bold, italic and code; the math popover gated on the dynamic import; alt ?? '' in image; the colour-slug guards in text-color. None are mentioned in the description — some look like fixes, but they should be stated (or split out) so they get reviewed as behaviour rather than slipping through as typing.

Casts: most of the as any / as HTMLElement | null casts are no-ops, because @wordpress/block-editor already resolves to the untyped stub. I removed them locally and tsc -b packages/format-library still passes; comments inline.

One process question: the five tools/eslint/suppressions.json entries were traded for inline eslint-disable-next-line react-hooks/refs. Updating the paths in suppressions.json would keep the central burn-down list accurate instead of scattering disables through the source. Was that deliberate?

@aduth

aduth commented Aug 26, 2026

Copy link
Copy Markdown
Member

Hey 👋 I wanted to give you a heads-up since this pull request removes or renames files that have an ESLint suppression on trunk.

#80123 enables an ESLint rule that requires that files containing JSX must use the .tsx file extension. Existing issues were suppressed, and our build will flag any stale suppressions as errors, so if the changes here update the file such that the suppression is no longer needed, you'll need to rebase against trunk and remove the unnecessary suppression.

What you'll need to do: You'll need to merge or rebase against the latest trunk, run npm run lint:js:prune-suppressions and commit the updated tools/eslint/suppressions.json file if there are any changes to commit.

This comment is automated, based on pull requests with recent activity that contain affected .js or .jsx files. But if you have any questions or if I can help with the migration in any way, please let me know and I'll do my best to help!

@im3dabasia

Copy link
Copy Markdown
Contributor Author

Hi @manzoorwanijk,

Apologies for the delay in addressing the feedback. When you get a moment, please have a look at this PR and let me know if anything else is needed to move it forward.

@manzoorwanijk manzoorwanijk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in much better shape now. Thank you for the clean up of any.

Two things left that I'd like to settle before this lands, both inline:

  1. The new else branch in onChangeLink replaces against the full value, which silently reintroduces the incorrectly-targeted-replacement bug (#41771) that the split was added to avoid.
  2. The title added to applyFormat in code's __unstableInputRule is inert, since only toggleFormat announces, so that behaviour-changes bullet should say "Bold and italic".

The rest are nits and won't block.

Comment thread packages/format-library/src/link/inline.tsx Outdated
Comment thread packages/format-library/src/code/index.tsx Outdated
Comment thread packages/format-library/src/non-breaking-space/index.tsx
Comment thread packages/format-library/src/types.ts Outdated
Comment thread packages/format-library/src/types.ts Outdated
Comment thread packages/format-library/src/text-color/index.tsx Outdated
Comment thread packages/format-library/src/text-color/inline.tsx
Comment thread packages/format-library/src/link/inline.tsx
Comment thread packages/format-library/src/language/index.tsx Outdated
@im3dabasia

Copy link
Copy Markdown
Contributor Author

Hi @manzoorwanijk, I really appreciate your quick feedback on this PR. I’m confident we’re close to the finish line with this issue.

Please check it once again, and as always, let me know if there’s anything that needs to be fixed.

@manzoorwanijk manzoorwanijk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your hard work. This looks great.

Let us fix the PR description before merge

Two bullets under "Behaviour changes" no longer match the code:

  1. "Bold, italic and code now announce apply/remove to screen readers". code reverted; only bold and italic changed.
  2. "Link: editing a link with no selection no longer throws; it replaces in place". It now bails out instead.

@manzoorwanijk

manzoorwanijk commented Sep 1, 2026

Copy link
Copy Markdown
Member

Wrong descriptions can sometimes mislead AI agents in future.

@im3dabasia

Copy link
Copy Markdown
Contributor Author

Description fixed, thanks! Merging this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Block editor /packages/block-editor [Package] Format library /packages/format-library [Package] Rich text /packages/rich-text [Type] Code Quality Issues or PRs that relate to code quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants