Skip to content

refactor(draft-js-editor): migrate DraftJSEditor from Flow to TypeScript - #4730

Merged
mergify[bot] merged 1 commit into
box:masterfrom
bonchevskyi:refactor/flow-to-ts-draft-js-editor
Jul 30, 2026
Merged

refactor(draft-js-editor): migrate DraftJSEditor from Flow to TypeScript#4730
mergify[bot] merged 1 commit into
box:masterfrom
bonchevskyi:refactor/flow-to-ts-draft-js-editor

Conversation

@bonchevskyi

@bonchevskyi bonchevskyi commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Convert DraftJSEditor component to TypeScript

This PR converts src/components/draft-js-editor from JavaScript with Flow to TypeScript.

Changes

  • Converted DraftJSEditor.js to DraftJSEditor.tsx with exported DraftJSEditorProps interface
  • Preserved the existing Flow props contract
  • Converted index.js, Storybook stories, and unit tests to TypeScript
  • Created .js.flow files for backward compatibility
  • Added DraftJSEditor exports to src/components/index.ts
  • Added @types/draft-js
  • Removed the unused isFocused default prop
  • Corrected the internal DraftJS blur event annotation

Testing

  • Ran all DraftJSEditor tests; all 8 pass
  • yarn lint:ts, ESLint, and flow check pass
  • Verified the Components/DraftJSEditor story builds successfully

Summary by CodeRabbit

  • New Features
    • Added a new Draft.js editor component with label/description support, placeholder text, error tooltips, and an “optional” indicator when not required.
    • Supports disabled/read-only mode and the ability to hide the visible label.
    • Improved accessibility wiring and return-key behavior when configured.
    • Exposed the new editor (and Breadcrumb) through the shared component exports.
  • Tests
    • Updated Draft.js editor tests and Storybook typings for stronger typing and coverage.
  • Chores
    • Updated development type definitions for Draft.js to improve editor-related developer experience.

@bonchevskyi
bonchevskyi requested a review from a team as a code owner July 29, 2026 13:35
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds a typed DraftJS editor with accessibility wiring, event handling, labels, disabled mode, and error tooltips. Exports it through component barrels, adds DraftJS typings, and updates its story and tests.

Changes

DraftJS editor

Layer / File(s) Summary
Editor contracts and rendering
src/components/draft-js-editor/DraftJSEditor.tsx, src/components/draft-js-editor/DraftJSEditor.js.flow
Defines props and implements DraftJS event forwarding, accessibility IDs, labels, descriptions, disabled mode, return-key handling, and error tooltips.
Public exports and TypeScript support
package.json, src/components/draft-js-editor/index.ts, src/components/draft-js-editor/index.js.flow, src/components/index.ts
Adds DraftJS typings and exposes the editor, its props, and component barrel exports.
Story and component test typing
src/components/draft-js-editor/DraftJSEditor.stories.tsx, src/components/draft-js-editor/__tests__/DraftJSEditor.test.tsx
Adds explicit editor-state and Enzyme typing and updates event-handler test fixtures and invocations.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Consumer
  participant DraftJSEditor
  participant DraftEditor
  participant Tooltip
  Consumer->>DraftJSEditor: Pass editorState and callbacks
  DraftJSEditor->>DraftEditor: Render editor and accessibility props
  DraftEditor->>DraftJSEditor: Emit change, focus, blur, or return
  DraftJSEditor->>Consumer: Forward event or updated editorState
  DraftJSEditor->>Tooltip: Show error.message when error exists
Loading

Possibly related PRs

Suggested reviewers: tjuanitas, tjiang-box, vitali-usik

Poem

A rabbit types where editors hop,
Labels and tooltips never stop.
Changes return, focus, and blur,
“Handled!” I thump with a whisker stir.
DraftJS is ready—snip, snap, pop!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is a custom change log, but it does not follow the repository's required PR template. Rewrite the PR description to match the repo template, including the ready-to-merge guidance and any required sections.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: migrating DraftJSEditor from Flow to TypeScript.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​types/​draft-js@​0.11.201001007581100

View full report

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/draft-js-editor/__tests__/DraftJSEditor.test.tsx`:
- Around line 61-62: Update the test’s onChange invocation to pass a valid
EditorState object, and type the callback according to the component’s actual
EditorState contract instead of casting it to () => void. Assert or preserve the
existing forwarding expectations so the test verifies the received EditorState
rather than allowing undefined.

In `@src/components/draft-js-editor/DraftJSEditor.js.flow`:
- Around line 37-59: Update DraftJSEditor’s Flow contract by removing the
isFocused default from defaultProps and changing handleBlur and the onBlur prop
typing to use the focus/blur event type emitted by DraftJS. Ensure handleBlur
forwards that event unchanged to onBlur, while leaving handleChange’s
EditorState contract intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a885fd77-9045-4887-a347-7f34937527d1

📥 Commits

Reviewing files that changed from the base of the PR and between 411145c and 59d3b63.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • package.json
  • src/components/draft-js-editor/DraftJSEditor.js.flow
  • src/components/draft-js-editor/DraftJSEditor.stories.tsx
  • src/components/draft-js-editor/DraftJSEditor.tsx
  • src/components/draft-js-editor/__tests__/DraftJSEditor.test.tsx
  • src/components/draft-js-editor/index.js.flow
  • src/components/draft-js-editor/index.ts
  • src/components/index.ts

Comment thread src/components/draft-js-editor/__tests__/DraftJSEditor.test.tsx

@coderabbitai coderabbitai Bot 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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/draft-js-editor/__tests__/DraftJSEditor.test.tsx`:
- Around line 61-62: Update the test’s onChange invocation to pass a valid
EditorState object, and type the callback according to the component’s actual
EditorState contract instead of casting it to () => void. Assert or preserve the
existing forwarding expectations so the test verifies the received EditorState
rather than allowing undefined.

In `@src/components/draft-js-editor/DraftJSEditor.js.flow`:
- Around line 37-59: Update DraftJSEditor’s Flow contract by removing the
isFocused default from defaultProps and changing handleBlur and the onBlur prop
typing to use the focus/blur event type emitted by DraftJS. Ensure handleBlur
forwards that event unchanged to onBlur, while leaving handleChange’s
EditorState contract intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a885fd77-9045-4887-a347-7f34937527d1

📥 Commits

Reviewing files that changed from the base of the PR and between 411145c and 59d3b63.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • package.json
  • src/components/draft-js-editor/DraftJSEditor.js.flow
  • src/components/draft-js-editor/DraftJSEditor.stories.tsx
  • src/components/draft-js-editor/DraftJSEditor.tsx
  • src/components/draft-js-editor/__tests__/DraftJSEditor.test.tsx
  • src/components/draft-js-editor/index.js.flow
  • src/components/draft-js-editor/index.ts
  • src/components/index.ts
🛑 Comments failed to post (1)
src/components/draft-js-editor/DraftJSEditor.js.flow (1)

37-59: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C2 'isFocused|handleBlur\s*=|onBlur:' \
  src/components/draft-js-editor/DraftJSEditor.tsx \
  src/components/draft-js-editor/DraftJSEditor.js.flow

Repository: box/box-ui-elements

Length of output: 2097


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '--- package copy:flow references ---\n'
rg -n '"copy:flow"|"flow"' package.json package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null || true

printf '\n--- relevant draft-js-editor files ---\n'
sed -n '1,90p' src/components/draft-js-editor/DraftJSEditor.tsx
printf '\n'
sed -n '1,90p' src/components/draft-js-editor/DraftJSEditor.js.flow

printf '\n--- imports for DraftJS type annotations ---\n'
sed -n '1,30p' src/components/draft-js-editor/DraftJSEditor.js.flow

Repository: box/box-ui-elements

Length of output: 248


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- package copy:flow references ---'
rg -n '"copy:flow"|"flow"' package.json package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null || true

printf '%s\n' ''
printf '%s\n' '--- relevant draft-js-editor files ---'
sed -n '1,90p' src/components/draft-js-editor/DraftJSEditor.tsx
printf '%s\n' ''
sed -n '1,90p' src/components/draft-js-editor/DraftJSEditor.js.flow

printf '%s\n' ''
printf '%s\n' '--- imports and relevant type annotations in flow file ---'
sed -n '1,80p' src/components/draft-js-editor/DraftJSEditor.js.flow

Repository: box/box-ui-elements

Length of output: 8652


🌐 Web query:

Draft.js Editor onBlur event API EditorState parameter callback event

💡 Result:

The Draft.js Editor component's onBlur prop callback does not receive an EditorState parameter; its signature is defined as (e: SyntheticFocusEvent) => void [1][2][3]. When the onBlur event is triggered, the Draft.js internal logic (specifically the editOnBlur function) handles the event, updates the selection state to reflect that the editor no longer has focus, and subsequently invokes your provided onBlur prop with the native synthetic focus event [4]. Because the onBlur callback does not receive the EditorState, if you need to access the current EditorState at the time of the blur event, you must rely on the state held in your component's scope (e.g., this.state.editorState or a React useState hook variable) [5][6]. Common considerations for onBlur implementations: - State Access: Since the callback only provides the event, you should reference your current component state directly to perform any operations based on the EditorState at the time of blurring [6]. - Synchronization: Developers often use the getSelection.getHasFocus method within the onChange handler to track focus changes effectively, as using setState inside onBlur can sometimes cause conflicts with the editor's update cycle [5][6]. - Preserve Selection: By default, Draft.js clears the DOM selection on blur. You can use the preserveSelectionOnBlur prop if you need to maintain native browser selection behavior [7][8].

Citations:


Synchronize the published Flow compatibility contract.

copy:flow preserves isFocused: false and declares handleBlur as accepting EditorState while calling onBlur(editorState), but DraftJS invokes onBlur with a focus event. Remove this stale default prop and type handleBlur/onBlur around the blur event/prop so Flow consumers match the runtime contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/draft-js-editor/DraftJSEditor.js.flow` around lines 37 - 59,
Update DraftJSEditor’s Flow contract by removing the isFocused default from
defaultProps and changing handleBlur and the onBlur prop typing to use the
focus/blur event type emitted by DraftJS. Ensure handleBlur forwards that event
unchanged to onBlur, while leaving handleChange’s EditorState contract intact.

@bonchevskyi
bonchevskyi force-pushed the refactor/flow-to-ts-draft-js-editor branch from 59d3b63 to 34b634f Compare July 30, 2026 10:43

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/draft-js-editor/DraftJSEditor.tsx`:
- Around line 20-47: Replace the generic Function and object types in
DraftJSEditorProps with concrete callback signatures and structured types
matching their usage in DraftJSEditor: type onBlur/onFocus with the expected
React synthetic event, onChange with its editor-state callback parameters,
onReturn with its return-handler contract, error with an optional message field,
and inputProps as a string-keyed prop record. Remove the corresponding casts in
the component implementation, including those around error, inputProps, and
onFocus.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 09e792f8-f510-4b70-ba93-3dd2cfcc06c9

📥 Commits

Reviewing files that changed from the base of the PR and between 59d3b63 and 34b634f.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • package.json
  • src/components/draft-js-editor/DraftJSEditor.js.flow
  • src/components/draft-js-editor/DraftJSEditor.stories.tsx
  • src/components/draft-js-editor/DraftJSEditor.tsx
  • src/components/draft-js-editor/__tests__/DraftJSEditor.test.tsx
  • src/components/draft-js-editor/index.js.flow
  • src/components/draft-js-editor/index.ts
  • src/components/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/draft-js-editor/DraftJSEditor.stories.tsx

Comment thread src/components/draft-js-editor/DraftJSEditor.tsx
@bonchevskyi
bonchevskyi force-pushed the refactor/flow-to-ts-draft-js-editor branch from 34b634f to 850bb6e Compare July 30, 2026 15:50
@mergify mergify Bot added the queued label Jul 30, 2026
@mergify

mergify Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • Entered queue2026-07-30 16:02 UTC · Rule: Automatic strict merge · triggered by rule Automatic merge queue
  • Checks skipped · PR is already up-to-date
  • Merged2026-07-30 16:02 UTC · at 850bb6e12cdfdc5d121bbd20adfdbc2265f8e2e4 · squash

This pull request spent 12 seconds in the queue, including 1 second running CI.

Required conditions to merge
  • github-review-approved [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = Summary
    • check-neutral = Summary
    • check-skipped = Summary
  • any of [🛡 GitHub branch protection]:
    • check-success = lint_test_build
    • check-neutral = lint_test_build
    • check-skipped = lint_test_build
  • any of [🛡 GitHub branch protection]:
    • check-success = license/cla
    • check-neutral = license/cla
    • check-skipped = license/cla
  • any of [🛡 GitHub branch protection]:
    • check-success = lint_pull_request
    • check-neutral = lint_pull_request
    • check-skipped = lint_pull_request

@mergify
mergify Bot merged commit b852471 into box:master Jul 30, 2026
9 of 11 checks passed

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
src/components/draft-js-editor/DraftJSEditor.js.flow (1)

21-35: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Flow entrypoint lacks a props type export, unlike the TS entrypoint. index.ts exports DraftJSEditorProps alongside the default, but the Flow shims only export the default component, so Flow consumers can't import an equivalent typed props contract.

  • src/components/draft-js-editor/DraftJSEditor.js.flow#L21-L35: export the Props type (e.g. export type Props = {...}) so it can be re-exported.
  • src/components/draft-js-editor/index.js.flow#L1-L2: add export type { Props } from './DraftJSEditor'; to mirror index.ts's DraftJSEditorProps export.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/draft-js-editor/DraftJSEditor.js.flow` around lines 21 - 35,
The Flow entrypoint must expose the editor props contract like the TypeScript
entrypoint. In src/components/draft-js-editor/DraftJSEditor.js.flow lines 21-35,
export the Props type; in src/components/draft-js-editor/index.js.flow lines
1-2, re-export Props from DraftJSEditor so Flow consumers can import it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/components/draft-js-editor/DraftJSEditor.js.flow`:
- Around line 21-35: The Flow entrypoint must expose the editor props contract
like the TypeScript entrypoint. In
src/components/draft-js-editor/DraftJSEditor.js.flow lines 21-35, export the
Props type; in src/components/draft-js-editor/index.js.flow lines 1-2, re-export
Props from DraftJSEditor so Flow consumers can import it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 72a8cd20-4927-4702-84b4-73b8830b926c

📥 Commits

Reviewing files that changed from the base of the PR and between 34b634f and 850bb6e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • package.json
  • src/components/draft-js-editor/DraftJSEditor.js.flow
  • src/components/draft-js-editor/DraftJSEditor.stories.tsx
  • src/components/draft-js-editor/DraftJSEditor.tsx
  • src/components/draft-js-editor/__tests__/DraftJSEditor.test.tsx
  • src/components/draft-js-editor/index.js.flow
  • src/components/draft-js-editor/index.ts
  • src/components/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • src/components/draft-js-editor/DraftJSEditor.stories.tsx

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants