about summary refs log tree commit diff
path: root/modules/react-native-ui-text-view/src
diff options
context:
space:
mode:
Diffstat (limited to 'modules/react-native-ui-text-view/src')
-rw-r--r--modules/react-native-ui-text-view/src/UITextView.tsx76
-rw-r--r--modules/react-native-ui-text-view/src/index.tsx42
2 files changed, 118 insertions, 0 deletions
diff --git a/modules/react-native-ui-text-view/src/UITextView.tsx b/modules/react-native-ui-text-view/src/UITextView.tsx
new file mode 100644
index 000000000..bbb45dccc
--- /dev/null
+++ b/modules/react-native-ui-text-view/src/UITextView.tsx
@@ -0,0 +1,76 @@
+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 (
+      <TextAncestorContext.Provider value={[true, flattenedStyle]}>
+        <RNUITextView
+          {...textDefaults}
+          {...rest}
+          ellipsizeMode={rest.ellipsizeMode ?? rest.lineBreakMode ?? 'tail'}
+          style={[{flex: 1}, flattenedStyle]}
+          onPress={undefined} // We want these to go to the children only
+          onLongPress={undefined}>
+          {React.Children.toArray(children).map((c, index) => {
+            if (React.isValidElement(c)) {
+              return c
+            } else if (typeof c === 'string') {
+              return (
+                <RNUITextViewChild
+                  key={index}
+                  style={flattenedStyle}
+                  text={c}
+                  {...rest}
+                />
+              )
+            }
+          })}
+        </RNUITextView>
+      </TextAncestorContext.Provider>
+    )
+  } else {
+    return (
+      <>
+        {React.Children.toArray(children).map((c, index) => {
+          if (React.isValidElement(c)) {
+            return c
+          } else if (typeof c === 'string') {
+            return (
+              <RNUITextViewChild
+                key={index}
+                style={flattenedStyle}
+                text={c}
+                {...rest}
+              />
+            )
+          }
+        })}
+      </>
+    )
+  }
+}
diff --git a/modules/react-native-ui-text-view/src/index.tsx b/modules/react-native-ui-text-view/src/index.tsx
new file mode 100644
index 000000000..d5bde136f
--- /dev/null
+++ b/modules/react-native-ui-text-view/src/index.tsx
@@ -0,0 +1,42 @@
+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<RNUITextViewProps>('RNUITextView')
+    : () => {
+        throw new Error(LINKING_ERROR)
+      }
+
+export const RNUITextViewChild =
+  UIManager.getViewManagerConfig &&
+  UIManager.getViewManagerConfig('RNUITextViewChild') != null
+    ? requireNativeComponent<RNUITextViewChildProps>('RNUITextViewChild')
+    : () => {
+        throw new Error(LINKING_ERROR)
+      }
+
+export * from './UITextView'