From 7fb117d213149dfee9d0e79292b267b3cd5bde0e Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 3 Apr 2024 18:05:03 -0700 Subject: [PATCH] Upgrade `UITextView` to latest (#3090) * uitextview use library w/ fixes bump bump multiple uitextview fixes * bump * update to latest * cleanup --- modules/react-native-ui-text-view/README.md | 61 ------- .../ios/RNUITextView-Bridging-Header.h | 3 - .../ios/RNUITextView.swift | 153 ------------------ .../ios/RNUITextViewChild.swift | 4 - .../ios/RNUITextViewChildShadow.swift | 56 ------- .../ios/RNUITextViewManager.m | 26 --- .../ios/RNUITextViewManager.swift | 30 ---- .../ios/RNUITextViewShadow.swift | 152 ----------------- .../react-native-ui-text-view/package.json | 9 -- .../react-native-ui-text-view.podspec | 42 ----- .../src/UITextView.tsx | 76 --------- .../react-native-ui-text-view/src/index.tsx | 42 ----- package.json | 2 +- src/components/Typography.tsx | 20 +-- src/view/com/util/text/Text.tsx | 9 +- yarn.lock | 7 +- 16 files changed, 17 insertions(+), 675 deletions(-) delete mode 100644 modules/react-native-ui-text-view/README.md delete mode 100644 modules/react-native-ui-text-view/ios/RNUITextView-Bridging-Header.h delete mode 100644 modules/react-native-ui-text-view/ios/RNUITextView.swift delete mode 100644 modules/react-native-ui-text-view/ios/RNUITextViewChild.swift delete mode 100644 modules/react-native-ui-text-view/ios/RNUITextViewChildShadow.swift delete mode 100644 modules/react-native-ui-text-view/ios/RNUITextViewManager.m delete mode 100644 modules/react-native-ui-text-view/ios/RNUITextViewManager.swift delete mode 100644 modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift delete mode 100644 modules/react-native-ui-text-view/package.json delete mode 100644 modules/react-native-ui-text-view/react-native-ui-text-view.podspec delete mode 100644 modules/react-native-ui-text-view/src/UITextView.tsx delete mode 100644 modules/react-native-ui-text-view/src/index.tsx diff --git a/modules/react-native-ui-text-view/README.md b/modules/react-native-ui-text-view/README.md deleted file mode 100644 index b19ac896..00000000 --- a/modules/react-native-ui-text-view/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# React Native UITextView - -Drop in replacement for `` that renders a `UITextView`, support selection and native translation features on iOS. - -## Installation - -In this project, no installation is required. The pod will be installed automatically during a `pod install`. - -In another project, clone the repo and copy the `modules/react-native-ui-text-view` directory to your own project -directory. Afterward, run `pod install`. - -## Usage - -Replace the outermost `` with ``. Styles and press events should be handled the same way they would -with ``. Both `` and `` are supported as children of the root ``. - -## Technical - -React Native's `Text` component allows for "infinite" nesting of further `Text` components. To make a true "drop-in", -we want to do the same thing. - -To achieve this, we first need to handle determining if we are dealing with an ancestor or root `UITextView` component. -We can implement similar logic to the `Text` component [see Text.js](https://github.com/facebook/react-native/blob/7f2529de7bc9ab1617eaf571e950d0717c3102a6/packages/react-native/Libraries/Text/Text.js). - -We create a context that contains a boolean to tell us if we have already rendered the root `UITextView`. We also store -the root styles so that we can apply those styles if the ancestor `UITextView`s have not overwritten those styles. - -All of our children are placed into `RNUITextView`, which is the main native view that will display the iOS `UITextView`. - -We next map each child into the view. We have to be careful here to check if the child's `children` prop is a string. If -it is, that means we have encountered what was once an RN `Text` component. RN doesn't let us pass plain text as -children outside of `Text`, so we instead just pass the text into the `text` prop on `RNUITextViewChild`. We continue -down the tree, until we run out of children. - -On the native side, we make use of the shadow view to calculate text container dimensions before the views are mounted. -We cannot simply set the `UITextView` text first, since React will not have properly measured the layout before this -occurs. - - -As for `Text` props, the following props are implemented: - -- All accessibility props -- `allowFontScaling` -- `adjustsFontSizeToFit` -- `ellipsizeMode` -- `numberOfLines` -- `onLayout` -- `onPress` -- `onTextLayout` -- `selectable` - -All `ViewStyle` props will apply to the root `UITextView`. Individual children will respect these `TextStyle` styles: - -- `color` -- `fontSize` -- `fontStyle` -- `fontWeight` -- `fontVariant` -- `letterSpacing` -- `lineHeight` -- `textDecorationLine` diff --git a/modules/react-native-ui-text-view/ios/RNUITextView-Bridging-Header.h b/modules/react-native-ui-text-view/ios/RNUITextView-Bridging-Header.h deleted file mode 100644 index e669b47e..00000000 --- a/modules/react-native-ui-text-view/ios/RNUITextView-Bridging-Header.h +++ /dev/null @@ -1,3 +0,0 @@ -#import -#import -#import diff --git a/modules/react-native-ui-text-view/ios/RNUITextView.swift b/modules/react-native-ui-text-view/ios/RNUITextView.swift deleted file mode 100644 index 3fb55873..00000000 --- a/modules/react-native-ui-text-view/ios/RNUITextView.swift +++ /dev/null @@ -1,153 +0,0 @@ -class RNUITextView: UIView { - var textView: UITextView - - @objc var numberOfLines: Int = 0 { - didSet { - textView.textContainer.maximumNumberOfLines = numberOfLines - } - } - @objc var selectable: Bool = true { - didSet { - textView.isSelectable = selectable - } - } - @objc var ellipsizeMode: String = "tail" { - didSet { - textView.textContainer.lineBreakMode = self.getLineBreakMode() - } - } - @objc var onTextLayout: RCTDirectEventBlock? - - override init(frame: CGRect) { - if #available(iOS 16.0, *) { - textView = UITextView(usingTextLayoutManager: false) - } else { - textView = UITextView() - } - - // Disable scrolling - textView.isScrollEnabled = false - // Remove all the padding - textView.textContainerInset = .zero - textView.textContainer.lineFragmentPadding = 0 - - // Remove other properties - textView.isEditable = false - textView.backgroundColor = .clear - - // Init - super.init(frame: frame) - self.clipsToBounds = true - - // Add the view - addSubview(textView) - - let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(callOnPress(_:))) - tapGestureRecognizer.isEnabled = true - textView.addGestureRecognizer(tapGestureRecognizer) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - // Resolves some animation issues - override func reactSetFrame(_ frame: CGRect) { - UIView.performWithoutAnimation { - super.reactSetFrame(frame) - } - } - - func setText(string: NSAttributedString, size: CGSize, numberOfLines: Int) -> Void { - self.textView.frame.size = size - self.textView.textContainer.maximumNumberOfLines = numberOfLines - self.textView.attributedText = string - self.textView.selectedTextRange = nil - - if let onTextLayout = self.onTextLayout { - var lines: [String] = [] - textView.layoutManager.enumerateLineFragments( - forGlyphRange: NSRange(location: 0, length: textView.attributedText.length)) - { (rect, usedRect, textContainer, glyphRange, stop) in - let characterRange = self.textView.layoutManager.characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil) - let line = (self.textView.text as NSString).substring(with: characterRange) - lines.append(line) - } - - onTextLayout([ - "lines": lines - ]) - } - } - - @IBAction func callOnPress(_ sender: UITapGestureRecognizer) -> Void { - // If we find a child, then call onPress - if let child = getPressed(sender) { - if textView.selectedTextRange == nil, let onPress = child.onPress { - onPress(["": ""]) - } else { - // Clear the selected text range if we are not pressing on a link - textView.selectedTextRange = nil - } - } - } - - // Try to get the pressed segment - func getPressed(_ sender: UITapGestureRecognizer) -> RNUITextViewChild? { - let layoutManager = textView.layoutManager - var location = sender.location(in: textView) - - // Remove the padding - location.x -= textView.textContainerInset.left - location.y -= textView.textContainerInset.top - - // Get the index of the char - let charIndex = layoutManager.characterIndex( - for: location, - in: textView.textContainer, - fractionOfDistanceBetweenInsertionPoints: nil - ) - - var lastUpperBound: String.Index? = nil - for child in self.reactSubviews() { - if let child = child as? RNUITextViewChild, let childText = child.text { - let fullText = self.textView.attributedText.string - - // We want to skip over the children we have already checked, otherwise we could run into - // collisions of similar strings (i.e. links that get shortened to the same hostname but - // different paths) - let range = fullText.range(of: childText, options: [], range: (lastUpperBound ?? String.Index(utf16Offset: 0, in: fullText) )..= lowerOffset, - charIndex <= upperOffset - { - return child - } else { - lastUpperBound = upperBound - } - } - } - } - - return nil - } - - func getLineBreakMode() -> NSLineBreakMode { - switch self.ellipsizeMode { - case "head": - return .byTruncatingHead - case "middle": - return .byTruncatingMiddle - case "tail": - return .byTruncatingTail - case "clip": - return .byClipping - default: - return .byTruncatingTail - } - } -} diff --git a/modules/react-native-ui-text-view/ios/RNUITextViewChild.swift b/modules/react-native-ui-text-view/ios/RNUITextViewChild.swift deleted file mode 100644 index c341c46e..00000000 --- a/modules/react-native-ui-text-view/ios/RNUITextViewChild.swift +++ /dev/null @@ -1,4 +0,0 @@ -class RNUITextViewChild: UIView { - @objc var text: String? - @objc var onPress: RCTDirectEventBlock? -} diff --git a/modules/react-native-ui-text-view/ios/RNUITextViewChildShadow.swift b/modules/react-native-ui-text-view/ios/RNUITextViewChildShadow.swift deleted file mode 100644 index 09119a36..00000000 --- a/modules/react-native-ui-text-view/ios/RNUITextViewChildShadow.swift +++ /dev/null @@ -1,56 +0,0 @@ -// We want all of our props to be available in the child's shadow view so we -// can create the attributed text before mount and calculate the needed size -// for the view. -class RNUITextViewChildShadow: RCTShadowView { - @objc var text: String = "" - @objc var color: UIColor = .black - @objc var fontSize: CGFloat = 16.0 - @objc var fontStyle: String = "normal" - @objc var fontWeight: String = "normal" - @objc var letterSpacing: CGFloat = 0.0 - @objc var lineHeight: CGFloat = 0.0 - @objc var pointerEvents: NSString? - - override func isYogaLeafNode() -> Bool { - return true - } - - override func didSetProps(_ changedProps: [String]!) { - guard let superview = self.superview as? RNUITextViewShadow else { - return - } - - if !YGNodeIsDirty(superview.yogaNode) { - superview.setAttributedText() - } - } - - func getFontWeight() -> UIFont.Weight { - switch self.fontWeight { - case "bold": - return .bold - case "normal": - return .regular - case "100": - return .ultraLight - case "200": - return .ultraLight - case "300": - return .light - case "400": - return .regular - case "500": - return .medium - case "600": - return .semibold - case "700": - return .semibold - case "800": - return .bold - case "900": - return .heavy - default: - return .regular - } - } -} diff --git a/modules/react-native-ui-text-view/ios/RNUITextViewManager.m b/modules/react-native-ui-text-view/ios/RNUITextViewManager.m deleted file mode 100644 index 32dfb3b2..00000000 --- a/modules/react-native-ui-text-view/ios/RNUITextViewManager.m +++ /dev/null @@ -1,26 +0,0 @@ -#import - -@interface RCT_EXTERN_MODULE(RNUITextViewManager, RCTViewManager) -RCT_REMAP_SHADOW_PROPERTY(numberOfLines, numberOfLines, NSInteger) -RCT_REMAP_SHADOW_PROPERTY(allowsFontScaling, allowsFontScaling, BOOL) - -RCT_EXPORT_VIEW_PROPERTY(numberOfLines, NSInteger) -RCT_EXPORT_VIEW_PROPERTY(onTextLayout, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(ellipsizeMode, NSString) -RCT_EXPORT_VIEW_PROPERTY(selectable, BOOL) - -@end - -@interface RCT_EXTERN_MODULE(RNUITextViewChildManager, RCTViewManager) -RCT_REMAP_SHADOW_PROPERTY(text, text, NSString) -RCT_REMAP_SHADOW_PROPERTY(color, color, UIColor) -RCT_REMAP_SHADOW_PROPERTY(fontSize, fontSize, CGFloat) -RCT_REMAP_SHADOW_PROPERTY(fontStyle, fontStyle, NSString) -RCT_REMAP_SHADOW_PROPERTY(fontWeight, fontWeight, NSString) -RCT_REMAP_SHADOW_PROPERTY(letterSpacing, letterSpacing, CGFloat) -RCT_REMAP_SHADOW_PROPERTY(lineHeight, lineHeight, CGFloat) -RCT_REMAP_SHADOW_PROPERTY(pointerEvents, pointerEvents, NSString) - -RCT_EXPORT_VIEW_PROPERTY(text, NSString) -RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) -@end diff --git a/modules/react-native-ui-text-view/ios/RNUITextViewManager.swift b/modules/react-native-ui-text-view/ios/RNUITextViewManager.swift deleted file mode 100644 index 297bcbbb..00000000 --- a/modules/react-native-ui-text-view/ios/RNUITextViewManager.swift +++ /dev/null @@ -1,30 +0,0 @@ -@objc(RNUITextViewManager) -class RNUITextViewManager: RCTViewManager { - override func view() -> (RNUITextView) { - return RNUITextView() - } - - @objc override static func requiresMainQueueSetup() -> Bool { - return true - } - - override func shadowView() -> RCTShadowView { - // Pass the bridge to the shadow view - return RNUITextViewShadow(bridge: self.bridge) - } -} - -@objc(RNUITextViewChildManager) -class RNUITextViewChildManager: RCTViewManager { - override func view() -> (RNUITextViewChild) { - return RNUITextViewChild() - } - - @objc override static func requiresMainQueueSetup() -> Bool { - return true - } - - override func shadowView() -> RCTShadowView { - return RNUITextViewChildShadow() - } -} diff --git a/modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift b/modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift deleted file mode 100644 index 5a462f6b..00000000 --- a/modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift +++ /dev/null @@ -1,152 +0,0 @@ -class RNUITextViewShadow: RCTShadowView { - // Props - @objc var numberOfLines: Int = 0 { - didSet { - if !YGNodeIsDirty(self.yogaNode) { - self.setAttributedText() - } - } - } - @objc var allowsFontScaling: Bool = true - - var attributedText: NSAttributedString = NSAttributedString() - var frameSize: CGSize = CGSize() - - var lineHeight: CGFloat = 0 - - var bridge: RCTBridge - - init(bridge: RCTBridge) { - self.bridge = bridge - super.init() - - // We need to set a custom measure func here to calculate the height correctly - YGNodeSetMeasureFunc(self.yogaNode) { node, width, widthMode, height, heightMode in - // Get the shadowview and determine the needed size to set - let shadowView = Unmanaged.fromOpaque(YGNodeGetContext(node)).takeUnretainedValue() - return shadowView.getNeededSize(maxWidth: width) - } - - // Subscribe to ynamic type size changes - NotificationCenter.default.addObserver( - self, - selector: #selector(preferredContentSizeChanged(_:)), - name: UIContentSizeCategory.didChangeNotification, - object: nil - ) - } - - @objc func preferredContentSizeChanged(_ notification: Notification) { - self.setAttributedText() - } - - // Returning true here will tell Yoga to not use flexbox and instead use our custom measure func. - override func isYogaLeafNode() -> Bool { - return true - } - - // We should only insert children that are UITextView shadows - override func insertReactSubview(_ subview: RCTShadowView!, at atIndex: Int) { - if subview.isKind(of: RNUITextViewChildShadow.self) { - super.insertReactSubview(subview, at: atIndex) - } - } - - // Every time the subviews change, we need to reformat and render the text. - override func didUpdateReactSubviews() { - self.setAttributedText() - } - - // Whenever we layout, update the UI - override func layoutSubviews(with layoutContext: RCTLayoutContext) { - // Don't do anything if the layout is dirty - if(YGNodeIsDirty(self.yogaNode)) { - return - } - - // Since we are inside the shadow view here, we have to find the real view and update the text. - self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in - guard let textView = viewRegistry?[self.reactTag] as? RNUITextView else { - return - } - textView.setText(string: self.attributedText, size: self.frameSize, numberOfLines: self.numberOfLines) - } - } - - override func dirtyLayout() { - super.dirtyLayout() - YGNodeMarkDirty(self.yogaNode) - } - - // Update the attributed text whenever changes are made to the subviews. - func setAttributedText() -> Void { - // Create an attributed string to store each of the segments - let finalAttributedString = NSMutableAttributedString() - - self.reactSubviews().forEach { child in - guard let child = child as? RNUITextViewChildShadow else { - return - } - let scaledFontSize = self.allowsFontScaling ? - UIFontMetrics.default.scaledValue(for: child.fontSize) : child.fontSize - let font = UIFont.systemFont(ofSize: scaledFontSize, weight: child.getFontWeight()) - - // Set some generic attributes that don't need ranges - let attributes: [NSAttributedString.Key:Any] = [ - .font: font, - .foregroundColor: child.color, - ] - - // Create the attributed string with the generic attributes - let string = NSMutableAttributedString(string: child.text, attributes: attributes) - - // Set the paragraph style attributes if necessary. We can check this by seeing if the provided - // line height is not 0.0. - let paragraphStyle = NSMutableParagraphStyle() - if child.lineHeight != 0.0 { - // Whenever we change the line height for the text, we are also removing the DynamicType - // adjustment for line height. We need to get the multiplier and apply that to the - // line height. - let scaleMultiplier = scaledFontSize / child.fontSize - paragraphStyle.minimumLineHeight = child.lineHeight * scaleMultiplier - paragraphStyle.maximumLineHeight = child.lineHeight * scaleMultiplier - - string.addAttribute( - NSAttributedString.Key.paragraphStyle, - value: paragraphStyle, - range: NSMakeRange(0, string.length) - ) - - // To calcualte the size of the text without creating a new UILabel or UITextView, we have - // to store this line height for later. - self.lineHeight = child.lineHeight - } else { - self.lineHeight = font.lineHeight - } - - finalAttributedString.append(string) - } - - self.attributedText = finalAttributedString - self.dirtyLayout() - } - - // To create the needed size we need to: - // 1. Get the max size that we can use for the view - // 2. Calculate the height of the text based on that max size - // 3. Determine how many lines the text is, and limit that number if it exceeds the max - // 4. Set the frame size and return the YGSize. YGSize requires Float values while CGSize needs CGFloat - func getNeededSize(maxWidth: Float) -> YGSize { - let maxSize = CGSize(width: CGFloat(maxWidth), height: CGFloat(MAXFLOAT)) - let textSize = self.attributedText.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, context: nil) - - var totalLines = Int(ceil(textSize.height / self.lineHeight)) - - if self.numberOfLines != 0, totalLines > self.numberOfLines { - totalLines = self.numberOfLines - } - - self.frameSize = CGSize(width: CGFloat(maxWidth), height: CGFloat(CGFloat(totalLines) * self.lineHeight)) - return YGSize(width: Float(self.frameSize.width), height: Float(self.frameSize.height)) - } -} diff --git a/modules/react-native-ui-text-view/package.json b/modules/react-native-ui-text-view/package.json deleted file mode 100644 index 184a9014..00000000 --- a/modules/react-native-ui-text-view/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "react-native-ui-text-view", - "version": "0.1.0", - "description": "UITextView in React Native on iOS", - "main": "src/index", - "author": "haileyok", - "license": "MIT", - "homepage": "https://github.com/bluesky-social/social-app/modules/react-native-ui-text-view" -} diff --git a/modules/react-native-ui-text-view/react-native-ui-text-view.podspec b/modules/react-native-ui-text-view/react-native-ui-text-view.podspec deleted file mode 100644 index 1e0dee93..00000000 --- a/modules/react-native-ui-text-view/react-native-ui-text-view.podspec +++ /dev/null @@ -1,42 +0,0 @@ -require "json" - -package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' - -Pod::Spec.new do |s| - s.name = "react-native-ui-text-view" - s.version = package["version"] - s.summary = package["description"] - s.homepage = package["homepage"] - s.license = package["license"] - s.authors = package["author"] - - s.platforms = { :ios => "11.0" } - s.source = { :git => ".git", :tag => "#{s.version}" } - - s.source_files = "ios/**/*.{h,m,mm,swift}" - - # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. - # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. - if respond_to?(:install_modules_dependencies, true) - install_modules_dependencies(s) - else - s.dependency "React-Core" - - # Don't install the dependencies when we run `pod install` in the old architecture. - if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" - s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", - "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" - } - s.dependency "React-RCTFabric" - s.dependency "React-Codegen" - s.dependency "RCT-Folly" - s.dependency "RCTRequired" - s.dependency "RCTTypeSafety" - s.dependency "ReactCommon/turbomodule/core" - end - end -end diff --git a/modules/react-native-ui-text-view/src/UITextView.tsx b/modules/react-native-ui-text-view/src/UITextView.tsx deleted file mode 100644 index bbb45dcc..00000000 --- a/modules/react-native-ui-text-view/src/UITextView.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react' -import {Platform, StyleSheet, TextProps, ViewStyle} from 'react-native' -import {RNUITextView, RNUITextViewChild} from './index' - -const TextAncestorContext = React.createContext<[boolean, ViewStyle]>([ - false, - StyleSheet.create({}), -]) -const useTextAncestorContext = () => React.useContext(TextAncestorContext) - -const textDefaults: TextProps = { - allowFontScaling: true, - selectable: true, -} - -export function UITextView({style, children, ...rest}: TextProps) { - const [isAncestor, rootStyle] = useTextAncestorContext() - - // Flatten the styles, and apply the root styles when needed - const flattenedStyle = React.useMemo( - () => StyleSheet.flatten([rootStyle, style]), - [rootStyle, style], - ) - - if (Platform.OS !== 'ios') { - throw new Error('UITextView is only available on iOS') - } - - if (!isAncestor) { - return ( - - - {React.Children.toArray(children).map((c, index) => { - if (React.isValidElement(c)) { - return c - } else if (typeof c === 'string') { - return ( - - ) - } - })} - - - ) - } else { - return ( - <> - {React.Children.toArray(children).map((c, index) => { - if (React.isValidElement(c)) { - return c - } else if (typeof c === 'string') { - return ( - - ) - } - })} - - ) - } -} diff --git a/modules/react-native-ui-text-view/src/index.tsx b/modules/react-native-ui-text-view/src/index.tsx deleted file mode 100644 index d5bde136..00000000 --- a/modules/react-native-ui-text-view/src/index.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { - requireNativeComponent, - UIManager, - Platform, - type ViewStyle, - TextProps, -} from 'react-native' - -const LINKING_ERROR = - `The package 'react-native-ui-text-view' doesn't seem to be linked. Make sure: \n\n` + - Platform.select({ios: "- You have run 'pod install'\n", default: ''}) + - '- You rebuilt the app after installing the package\n' + - '- You are not using Expo Go\n' - -export interface RNUITextViewProps extends TextProps { - children: React.ReactNode - style: ViewStyle[] -} - -export interface RNUITextViewChildProps extends TextProps { - text: string - onTextPress?: (...args: any[]) => void - onTextLongPress?: (...args: any[]) => void -} - -export const RNUITextView = - UIManager.getViewManagerConfig && - UIManager.getViewManagerConfig('RNUITextView') != null - ? requireNativeComponent('RNUITextView') - : () => { - throw new Error(LINKING_ERROR) - } - -export const RNUITextViewChild = - UIManager.getViewManagerConfig && - UIManager.getViewManagerConfig('RNUITextViewChild') != null - ? requireNativeComponent('RNUITextViewChild') - : () => { - throw new Error(LINKING_ERROR) - } - -export * from './UITextView' diff --git a/package.json b/package.json index b4018463..efd48030 100644 --- a/package.json +++ b/package.json @@ -174,7 +174,7 @@ "react-native-safe-area-context": "4.8.2", "react-native-screens": "~3.29.0", "react-native-svg": "14.1.0", - "react-native-ui-text-view": "link:./modules/react-native-ui-text-view", + "react-native-uitextview": "^1.1.6", "react-native-url-polyfill": "^1.3.0", "react-native-uuid": "^2.0.1", "react-native-version-number": "^0.3.6", diff --git a/src/components/Typography.tsx b/src/components/Typography.tsx index f8b3ad1b..31dd931c 100644 --- a/src/components/Typography.tsx +++ b/src/components/Typography.tsx @@ -1,14 +1,9 @@ import React from 'react' -import { - Text as RNText, - StyleProp, - TextStyle, - TextProps as RNTextProps, -} from 'react-native' -import {UITextView} from 'react-native-ui-text-view' +import {StyleProp, TextProps as RNTextProps, TextStyle} from 'react-native' +import {UITextView} from 'react-native-uitextview' -import {useTheme, atoms, web, flatten} from '#/alf' -import {isIOS, isNative} from '#/platform/detection' +import {isNative} from '#/platform/detection' +import {atoms, flatten, useTheme, web} from '#/alf' export type TextProps = RNTextProps & { /** @@ -61,11 +56,8 @@ export function normalizeTextStyles(styles: StyleProp) { export function Text({style, selectable, ...rest}: TextProps) { const t = useTheme() const s = normalizeTextStyles([atoms.text_sm, t.atoms.text, flatten(style)]) - return selectable && isIOS ? ( - - ) : ( - - ) + + return } export function createHeadingElement({level}: {level: number}) { diff --git a/src/view/com/util/text/Text.tsx b/src/view/com/util/text/Text.tsx index 37d66558..2ea9586e 100644 --- a/src/view/com/util/text/Text.tsx +++ b/src/view/com/util/text/Text.tsx @@ -1,9 +1,10 @@ import React from 'react' import {Text as RNText, TextProps} from 'react-native' -import {s, lh} from 'lib/styles' -import {useTheme, TypographyVariant} from 'lib/ThemeContext' +import {UITextView} from 'react-native-uitextview' + +import {lh, s} from 'lib/styles' +import {TypographyVariant, useTheme} from 'lib/ThemeContext' import {isIOS, isWeb} from 'platform/detection' -import {UITextView} from 'react-native-ui-text-view' export type CustomTextProps = TextProps & { type?: TypographyVariant @@ -36,6 +37,8 @@ export function Text({ return ( {children} diff --git a/yarn.lock b/yarn.lock index c81f1206..a2941d5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18721,9 +18721,10 @@ react-native-svg@14.1.0: css-select "^5.1.0" css-tree "^1.1.3" -"react-native-ui-text-view@link:./modules/react-native-ui-text-view": - version "0.0.0" - uid "" +react-native-uitextview@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/react-native-uitextview/-/react-native-uitextview-1.1.6.tgz#a70d039f415158445c90de8e8e546a7c3b251d6d" + integrity sha512-OTGTw4Y2DDn4dHTwN7aKOndXP6NoS/AS35Rj/Rsss+KRsGHToiv2g3ZdzQ0ZhZabhwl1u+Oht+wSU/FU+SoJ+Q== react-native-url-polyfill@^1.3.0: version "1.3.0"