Skip to content

feat(input): localize format & selection submenu labels#443

Open
eszlamczyk wants to merge 7 commits into
mainfrom
feat/labels-for-input-context-menu
Open

feat(input): localize format & selection submenu labels#443
eszlamczyk wants to merge 7 commits into
mainfrom
feat/labels-for-input-context-menu

Conversation

@eszlamczyk

@eszlamczyk eszlamczyk commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

What/Why?

Extends PR #415 localizable-labels pattern from EnrichedMarkdownText to the input context menu introduced in PR #409. Apps that localize the renderer's selectionMenuConfig would otherwise still see an English "Format / Bold / Italic / … / Copy as Markdown" submenu on EnrichedMarkdownTextInput - this closes that gap.

Nine new label slots, all opt-in and additive to existing config:

  • formatMenuConfig.{bold,italic,underline,strikethrough,spoiler,link} - each now takes { enabled?, label? } instead of boolean.
  • inputSelectionMenuConfig.format and .copyAsMarkdown - same shape; format.label controls the submenu title itself.

The legacy boolean form keeps working at runtime and logs a one-time warnOnce deprecation; removed in 0.8. Same shape evolution as PR #415.
JS resolves the English defaults so native code carries no fallback strings - Android / iOS / macOS just read labels straight from the config struct or data class, matching the convention from #415.

Refactor: normalizeMenuItem + warnOnce extracted from src/native/EnrichedMarkdownText.tsx into src/shared/normalizeMenuItem.ts so both selectionMenuConfig (text) and formatMenuConfig / inputSelectionMenuConfig (input) share deprecation rules and fallback semantics.

Not in scope (intentional):

  • System Cut / Copy / Paste / Select All in the input — UIKit (UITextView) and Android's ActionMode add these and they're already localised by the device language. No prop needed.
  • Link prompt dialog strings ("Add Link", "Edit Link", "Update", "Add", "Cancel", URL placeholder) - separate UI surface; would expand the i18n API to dialog text. Worth a follow-up/discussion with the team if needed.
  • iOS image long-press sheet ("Save to Camera Roll", "Copy", …) - UIKit owns this for NSTextAttachment images; would require attaching UIContextMenuInteraction to image regions. TODO already noted in ios/utils/EditMenuUtils.h.

Platforms: iOS, Android, macOS

Testing

apps/react-native-example/.rnstorybook/stories/components/EnrichedMarkdownTextInput/props/FormatMenu.stories.tsx extended with three stories mirroring the SelectionMenu story layout:

  1. Default - Italian labels for all 9 slots; every label + enabled toggle exposed as controls so you can dial them live.
  2. EnglishDefaults - no formatMenuConfig / inputSelectionMenuConfig; verifies the JS-side fallback path resolves to the built-in English labels across all three platforms.
  3. DeprecatedBooleanForm - passes legacy bold: false / copyAsMarkdown: false; verifies the warnOnce deprecation fires once and visibility still toggles correctly through the compat shim.

Screenshots

iOS Android
Usage demo
Screen.Recording.2026-06-25.at.14.32.47.mov
Screen.Recording.2026-06-25.at.14.34.34.mov
Warning image image

PR Checklist

  • Code compiles and runs on iOS
  • Code compiles and runs on Android
  • Updated documentation/README if applicable
  • Ran example app to verify changes
  • E2E tests are passing
  • Required E2E tests have been added (if applicable)

Adresses #407

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR extends the localized-labels pattern used by EnrichedMarkdownText to the EnrichedMarkdownTextInput selection context menu, so the “Format” submenu and its items (plus “Copy as Markdown”) can be localized via JS-provided labels while keeping native code free of fallback strings.

Changes:

  • Introduces a shared normalizeMenuItem helper (plus warnOnce) to normalize { enabled, label } items and support legacy boolean configs with a one-time deprecation warning.
  • Expands input context-menu config plumbing to carry submenu/action/item labels through codegen → iOS/Android menu construction.
  • Updates the example Storybook stories to demonstrate defaults, localized labels, and the deprecated boolean runtime shim.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/react-native-enriched-markdown/src/shared/normalizeMenuItem.ts New shared normalization + deprecation warning utility used by text + input menu config.
packages/react-native-enriched-markdown/src/native/EnrichedMarkdownText.tsx Switches selection menu normalization to shared normalizeMenuItem.
packages/react-native-enriched-markdown/src/EnrichedMarkdownTextInputNativeComponent.ts Extends internal config structs with *Label fields for native consumption.
packages/react-native-enriched-markdown/src/EnrichedMarkdownTextInput.tsx Normalizes input menu config to always provide concrete labels + supports legacy booleans at runtime.
packages/react-native-enriched-markdown/ios/input/EnrichedMarkdownTextInput+Internal.h Adds label pointers to config structs for iOS/macOS menus.
packages/react-native-enriched-markdown/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm Uses config-provided labels for iOS/macOS menu titles and items.
packages/react-native-enriched-markdown/ios/input/EnrichedMarkdownTextInput.mm Stores strong owners for label strings and threads them into config structs.
packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt Uses config-provided labels for Android submenu title, items, and “Copy as Markdown”.
packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt Parses label fields from the RN prop map into Kotlin config data classes.
apps/react-native-example/.rnstorybook/stories/components/EnrichedMarkdownTextInput/props/FormatMenu.stories.tsx Adds stories covering localized labels, English defaults, and deprecated boolean form.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/react-native-enriched-markdown/ios/input/EnrichedMarkdownTextInput.mm Outdated
Comment thread packages/react-native-enriched-markdown/ios/input/EnrichedMarkdownTextInput.mm Outdated
@eszlamczyk eszlamczyk changed the title feat: label inputs context menu feat(input): localize format & selection submenu labels Jun 25, 2026
@eszlamczyk eszlamczyk requested a review from hryhoriiK97 June 25, 2026 12:39
@eszlamczyk eszlamczyk marked this pull request as ready for review June 25, 2026 12:39

@hryhoriiK97 hryhoriiK97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM! I've left one comment — please take a look at it.

Comment thread packages/react-native-enriched-markdown/src/normalizeMenuItem.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants