Skip to content

feat: experimental macOS support - #801

Draft
hejsztynx wants to merge 12 commits into
mainfrom
@ksienkiewicz/macos-support
Draft

hejsztynx wants to merge 12 commits into
mainfrom
@ksienkiewicz/macos-support

Conversation

@hejsztynx

Copy link
Copy Markdown
Collaborator

Summary

Experimental macOS support.

Implementation uses the already existing iOS code, patching the platform differences using conditional directives, so changes to the iOS-compiled code is effectively as minimal as possible.

The main macOS platform specific differences that required patching the logic:

  • it internally derives typingAttrbutes from the previous character
  • doesn't persist textLists in paragraph style attributes
  • on selection changes it resets typingAttributes

Provided an example app, similar to already existing ones on other platforms.

What's not available yet:

  • so far there is no written documentation for docs.swmansion
  • no e2e tests

Test Plan

Overall, the components should behave identically to the iOS.

For more info and instructions how to run the app, visit MACOS.md in /docs

Copilot AI lite review requested due to automatic review settings September 21, 2026 12:37
@hejsztynx
hejsztynx marked this pull request as draft September 21, 2026 12:37

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 review overview

🔵 Needs a closer look

It introduces substantial cross-platform native (UIKit/AppKit/TextKit) changes and a new macOS app surface area without automated coverage to validate behavioral parity.

Review effort: Lite
Findings: 1 Low severity

Open (1)
What changed in this PR

Adds experimental macOS (react-native-macos) support by reusing the existing iOS native implementation and patching platform differences behind a small UIKit/AppKit compatibility layer, plus a dedicated macOS example app and docs.

Changes:

  • Introduces an EnrichedPlatform compatibility layer and updates native iOS code to route through it (selection, insets, drawing, pasteboard, etc.) for macOS builds.
  • Extends the library’s native packaging/config to include macOS (podspec :osx, workspace/scripts/turbo task updates).
  • Adds a standalone apps/example-macos app and docs/MACOS.md with setup and behavior notes.
File Description
turbo.json Adds a Turbo pipeline task for building the macOS example workspace.
src/​types.ts Updates JSDoc platform annotations and clarifies macOS-ignored props.
README.md Mentions experimental macOS support in the feature list.
ReactNativeEnrichedHtml.podspec Declares macOS (osx) platform support.
package.json Adds macOS example workspace/scripts and typecheck coverage for it.
ios/​utils/​ZeroWidthSpaceUtils.mm Switches to platform-neutral first-responder + selection setters.
ios/​utils/​ZeroWidthSpaceUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​WordsUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​TextListsUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​TextInsertionUtils.mm Preserves typingAttributes on macOS and uses compat selection APIs.
ios/​utils/​TextInsertionUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​TextBlockTapGestureRecognizer.mm Compiles out iOS-only gesture recognizer on macOS.
ios/​utils/​TextBlockTapGestureRecognizer.h Adds pragma once + platform gating for iOS-only recognizer.
ios/​utils/​ShortcutsUtils.mm Uses compat selection setter (avoids AppKit typingAttributes resets).
ios/​utils/​ShortcutsUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​RangeUtils.mm Generalizes APIs to accept EnrichedBaseTextView.
ios/​utils/​RangeUtils.h Replaces UIKit import and updates signatures to EnrichedBaseTextView.
ios/​utils/​ParagraphAttributesUtils.mm Uses compat marked-text check for IME handling.
ios/​utils/​ParagraphAttributesUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​KeyboardUtils.mm Compiles out iOS keyboard mapping utility on macOS.
ios/​utils/​KeyboardUtils.h Compiles out iOS keyboard mapping interface on macOS.
ios/​utils/​ItalicUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​EnrichedTextTouchHandler.mm Uses platform-neutral insets and text view base type.
ios/​utils/​EnrichedTextTouchHandler.h Replaces UIKit import with platform compatibility header.
ios/​utils/​DotReplacementUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​CheckboxHitTestUtils.mm Uses EnrichedBaseTextView and compat insets for hit testing.
ios/​utils/​CheckboxHitTestUtils.h Replaces UIKit import with platform compatibility header.
ios/​utils/​AttachmentLayoutUtils.mm Adapts attachment image view behavior for AppKit (tinting, scaling, z-order).
ios/​utils/​AttachmentLayoutUtils.h Replaces UIKit import and updates signatures to EnrichedBaseTextView.
ios/​utils/​AlignmentUtils.h Replaces UIKit import with platform compatibility header.
ios/​textHtmlParser/​TextHtmlParser.h Replaces UIKit import with platform compatibility header.
ios/​styles/​MentionStyle.mm Uses compat selection setter.
ios/​styles/​LinkStyle.mm Uses compat selection setter.
ios/​styles/​AlignmentStyle.mm Uses EnrichedBaseTextView for typing-attributes inspection.
ios/​platform/​EnrichedPlatform.mm Adds UIKit/AppKit shims (selection, tint, drawing, rounded paths, paste behavior helpers).
ios/​platform/​EnrichedPlatform.h Declares cross-platform UIKit/AppKit compatibility layer used across headers.
ios/​interfaces/​TextDecorationLineEnum.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​StyleTypeEnum.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​StylePair.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​StyleBase.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​MentionStyleProps.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​MentionParams.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​MediaAttachment.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​LinkRegexConfig.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​LinkData.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​ImageData.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​ImageAttachment.mm Fixes macOS scale handling for cache cost calculation.
ios/​interfaces/​EnrichedViewHost.h Swaps host text view type to EnrichedBaseTextView.
ios/​interfaces/​AttributeEntry.h Replaces UIKit import with platform compatibility header.
ios/​interfaces/​AlignmentEntry.h Replaces UIKit import with platform compatibility header.
ios/​inputHtmlParser/​InputHtmlParser.h Replaces UIKit import with platform compatibility header.
ios/​inputAttributesManager/​InputAttributesManager.mm Adds macOS-specific typingAttributes/textLists handling.
ios/​inputAttributesManager/​InputAttributesManager.h Replaces UIKit import with platform compatibility header.
ios/​htmlParser/​HtmlParser.h Replaces UIKit import with platform compatibility header.
ios/​extensions/​StringExtension.h Replaces UIKit import with platform compatibility header.
ios/​extensions/​LayoutManagerExtension.mm Routes rounded-rect drawing + fill/image helpers through platform layer.
ios/​extensions/​LayoutManagerExtension.h Replaces UIKit import with platform compatibility header.
ios/​extensions/​ImageExtension.mm Adds macOS implementation for “animated image” data handling.
ios/​extensions/​ImageExtension.h Replaces UIKit import with platform compatibility header.
ios/​extensions/​FontExtension.h Replaces UIKit import with platform compatibility header.
ios/​extensions/​ColorExtension.h Replaces UIKit import with platform compatibility header.
ios/​EnrichedTextView.mm Builds an explicit TextKit 1 stack on macOS; adapts selectionColor + Dynamic Type hooks.
ios/​EnrichedTextView.h Switches stored text view to EnrichedBaseTextView and imports platform header.
ios/​enrichedTextTextView/​EnrichedTextTextView.mm Adds macOS pasteboard copy support + mouse event forwarding.
ios/​enrichedTextTextView/​EnrichedTextTextView.h Changes base class to EnrichedBaseTextView and imports platform header.
ios/​EnrichedTextInputView.mm Adds macOS TextKit 1 stack + scroll view hosting + AppKit delegate/menu plumbing.
ios/​EnrichedTextInputView.h Imports platform header and exposes shared macOS/iOS handlers.
ios/​enrichedInputTextView/​EnrichedInputTextView.mm Adds AppKit paste/cut/copy and checkbox click hit-testing for macOS.
ios/​enrichedInputTextView/​EnrichedInputTextView.h Changes base class to EnrichedBaseTextView and imports platform header.
ios/​config/​EnrichedConfig.mm Uses platform-scaled font helpers and adds AppKit checkbox image drawing.
ios/​config/​EnrichedConfig.h Replaces UIKit import with platform compatibility header.
docs/​MACOS.md Adds macOS installation and feature/support matrix documentation.
apps/​example-macos/​tsconfig.json Adds TS config for the macOS example workspace.
apps/​example-macos/​src/​hooks/​useUserMention.ts Adds mock user mention filtering hook for the macOS example.
apps/​example-macos/​src/​hooks/​useEditorState.ts Adds editor state orchestration for the macOS example.
apps/​example-macos/​src/​hooks/​useChannelMention.ts Adds mock channel mention filtering hook for the macOS example.
apps/​example-macos/​src/​components/​ModalShell.tsx Implements a macOS-safe “modal” overlay (no native Modal host).
apps/​example-macos/​src/​components/​MentionPopup.tsx Adds mention picker popup component for the macOS example.
apps/​example-macos/​src/​components/​LinkModal.tsx Adds link editing “modal” UI for the macOS example.
apps/​example-macos/​src/​components/​ImageModal.tsx Adds image insertion “modal” UI for the macOS example.
apps/​example-macos/​src/​App.tsx Adds the macOS example app UI wiring EnrichedTextInput + EnrichedText.
apps/​example-macos/​react-native.config.js Configures monorepo dependency resolution and explicit platforms for codegen.
apps/​example-macos/​package.json Adds macOS example app dependencies and scripts.
apps/​example-macos/​metro.config.js Adds Metro config with explicit react-native-macos mapping.
apps/​example-macos/​macos/​PrivacyInfo.xcprivacy Adds privacy manifest for the macOS example app.
apps/​example-macos/​macos/​Podfile Adds CocoaPods setup for react-native-macos + new architecture enablement.
apps/​example-macos/​macos/​EnrichedMacOSExample.xcworkspace/​contents.xcworkspacedata Adds the Xcode workspace for the macOS example.
apps/​example-macos/​macos/​EnrichedMacOSExample.xcodeproj/​xcshareddata/​xcschemes/​EnrichedMacOSExample-macOS.xcscheme Adds the shared scheme for building/running the macOS example.
apps/​example-macos/​macos/​EnrichedMacOSExample.xcodeproj/​project.pbxproj Adds the macOS Xcode project configuration and build phases.
apps/​example-macos/​macos/​EnrichedMacOSExample-macOS/​main.m Adds macOS app entry point.
apps/​example-macos/​macos/​EnrichedMacOSExample-macOS/​Info.plist Adds macOS app Info.plist and new-arch flag.
apps/​example-macos/​macos/​EnrichedMacOSExample-macOS/​EnrichedMacOSExample.entitlements Adds sandbox/network/file entitlements for the macOS app.
apps/​example-macos/​macos/​EnrichedMacOSExample-macOS/​Base.lproj/​Main.storyboard Adds the macOS app storyboard/menu structure.
apps/​example-macos/​macos/​EnrichedMacOSExample-macOS/​Assets.xcassets/​Contents.json Adds asset catalog metadata.
apps/​example-macos/​macos/​EnrichedMacOSExample-macOS/​Assets.xcassets/​AppIcon.appiconset/​Contents.json Adds app icon set metadata.
apps/​example-macos/​macos/​EnrichedMacOSExample-macOS/​AppDelegate.mm Adds macOS RN app delegate (Fabric/concurrentRoot wiring).
apps/​example-macos/​macos/​EnrichedMacOSExample-macOS/​AppDelegate.h Adds macOS RN app delegate header.
apps/​example-macos/​macos/​.xcode.env Adds Xcode script environment configuration.
apps/​example-macos/​macos/​.gitignore Ignores CocoaPods output for the macOS example.
apps/​example-macos/​index.js Registers the macOS example root component.
apps/​example-macos/​Gemfile.lock Locks Ruby/CocoaPods dependencies for the macOS example.
apps/​example-macos/​Gemfile Adds Ruby gem constraints for CocoaPods/Xcodeproj tooling.
apps/​example-macos/​babel.config.js Adds Babel config aligned with the monorepo/bob setup.
apps/​example-macos/​app.json Adds RN app metadata for the macOS example.
apps/​example-macos/​.watchmanconfig Adds Watchman config for the macOS example.
Files not reviewed (1)
  • apps/example-macos/macos/EnrichedMacOSExample.xcworkspace/contents.xcworkspacedata: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1 to +5
#import "EnrichedPlatform.h"

#import <objc/runtime.h>

#if !TARGET_OS_OSX

This branch has not been deployed

No deployments
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.

4 participants