Skip to content

Commit

Permalink
Merge pull request #537 from jpudysz/feature/rtc
Browse files Browse the repository at this point in the history
feat: add support for raw RTCView and RCTText
  • Loading branch information
jpudysz authored Jan 30, 2025
2 parents a2737f3 + fcce95c commit 2ea3bf4
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 23 deletions.
5 changes: 5 additions & 0 deletions components/native/NativeText/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"main": "../../../lib/commonjs/components/native/NativeText.js",
"module": "../../../lib/module/components/native/NativeText.js",
"react-native": "../../../src/components/native/NativeText.native.tsx"
}
5 changes: 5 additions & 0 deletions components/native/NativeView/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"main": "../../../lib/commonjs/components/native/NativeView.js",
"module": "../../../lib/module/components/native/NativeView.js",
"react-native": "../../../src/components/native/NativeView.native.tsx"
}
13 changes: 9 additions & 4 deletions expo-example/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Link } from 'expo-router'
import React from 'react'
import { Pressable, Text, View } from 'react-native'
import { Link } from 'expo-router'
import { Pressable, View, Text } from 'react-native'
import { StyleSheet } from 'react-native-unistyles'

export default function HomeScreen() {
Expand All @@ -11,12 +11,12 @@ export default function HomeScreen() {
return (
<View style={styles.container}>
<View style={styles.test}>
<Text>
<Text style={styles.typography}>
Hello world
</Text>
<Link href="/explore" asChild>
<Pressable style={styles.button}>
<Text>
<Text style={styles.typography}>
Explore
</Text>
</Pressable>
Expand All @@ -33,6 +33,11 @@ const styles = StyleSheet.create(theme => ({
alignItems: 'center',
backgroundColor: theme.colors.backgroundColor
},
typography: {
fontSize: 20,
fontWeight: 'bold',
color: theme.colors.typography
},
test: {
width: '100%',
variants: {
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
"precommit": "concurrently 'yarn tsc' 'yarn lint' 'yarn test'",
"release": "release-it"
},
"main": "lib/commonjs/index",
"module": "lib/module/index",
"main": "lib/commonjs/index.js",
"module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts",
"source": "src/index",
"exports": {
".": {
"types": "./lib/typescript/src/index.d.ts",
"module": "./lib/module/index",
"default": "./lib/commonjs/index",
"module": "./lib/module/index.js",
"default": "./lib/commonjs/index.js",
"react-native": "./src/index"
},
"./components/native/*": {
Expand All @@ -34,8 +34,8 @@
"./package.json": "./package.json",
"./server": {
"types": "./lib/typescript/src/server/index.d.ts",
"module": "./lib/module/server/index",
"default": "./lib/commonjs/server/index",
"module": "./lib/module/server/index.js",
"default": "./lib/commonjs/server/index.js",
"react-native": "./src/server"
}
},
Expand Down
22 changes: 21 additions & 1 deletion plugin/consts.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,33 @@ const REPLACE_WITH_UNISTYLES_PATHS = [

// this is more powerful API as it allows to convert unmatched imports to Unistyles
// { path: string, imports: Array<{ name: string, isDefault: boolean, path: string, mapTo: string }> }
// name <- target import name
// path => node_modules path
// imports:
// name? <- target import name if isDefault is false
// isDefault <- is the import default?
// path <- path to the target import
// mapTo <- name of the Unistyles component
const REPLACE_WITH_UNISTYLES_EXOTIC_PATHS = []

// this list will additionally detect React Native direct imports
const NATIVE_COMPONENTS_PATHS = {
imports: [
{
name: 'NativeText',
isDefault: false,
path: 'react-native/Libraries/Text/TextNativeComponent',
mapTo: 'NativeText'
},
{
isDefault: true,
path: 'react-native/Libraries/Components/View/ViewNativeComponent',
mapTo: 'NativeView'
}
]
}

module.exports = {
NATIVE_COMPONENTS_PATHS,
REACT_NATIVE_COMPONENT_NAMES,
REPLACE_WITH_UNISTYLES_PATHS,
REPLACE_WITH_UNISTYLES_EXOTIC_PATHS
Expand Down
34 changes: 23 additions & 11 deletions plugin/exotic.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,40 @@ function handleExoticImport(t, path, state, exoticImport) {

specifiers.forEach(specifier => {
for (const rule of exoticImport.imports) {
const hasMatchingImportType = !rule.isDefault || t.isImportDefaultSpecifier(specifier)
const hasMatchingImportName = rule.name === specifier.local.name
const hasMatchingImportType = (!rule.isDefault && t.isImportSpecifier(specifier)) || (rule.isDefault && t.isImportDefaultSpecifier(specifier))
const hasMatchingImportName = rule.isDefault || (!rule.isDefault && rule.name === specifier.local.name)
const hasMatchingPath = rule.path === source.value

if (!hasMatchingImportType || !hasMatchingImportName || !hasMatchingPath) {
continue
}

const newImport = t.importDeclaration(
[t.importSpecifier(t.identifier(rule.mapTo), t.identifier(rule.mapTo))],
t.stringLiteral(state.opts.isLocal
? state.file.opts.filename.split('react-native-unistyles').at(0).concat(`react-native-unistyles/components/native/${rule.mapTo}`)
: `react-native-unistyles/components/native/${rule.mapTo}`
if (t.isImportDefaultSpecifier(specifier)) {
const newImport = t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(specifier.local.name))],
t.stringLiteral(state.opts.isLocal
? state.file.opts.filename.split('react-native-unistyles').at(0).concat(`react-native-unistyles/components/native/${rule.mapTo}`)
: `react-native-unistyles/components/native/${rule.mapTo}`
)
)
)

// remove old import
if (t.isImportDefaultSpecifier(specifier)) {
path.replaceWith(newImport)
} else {
const newImport = t.importDeclaration(
[t.importSpecifier(t.identifier(rule.mapTo), t.identifier(rule.mapTo))],
t.stringLiteral(state.opts.isLocal
? state.file.opts.filename.split('react-native-unistyles').at(0).concat(`react-native-unistyles/components/native/${rule.mapTo}`)
: `react-native-unistyles/components/native/${rule.mapTo}`
)
)

path.node.specifiers = specifiers.filter(s => s !== specifier)
path.unshift(newImport)

if (path.node.specifiers.length === 0) {
path.replaceWith(newImport)
} else {
path.insertBefore(newImport)
}
}

return
Expand Down
6 changes: 5 additions & 1 deletion plugin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { addUnistylesImport, isInsideNodeModules } = require('./import')
const { hasStringRef } = require('./ref')
const { isUnistylesStyleSheet, analyzeDependencies, addStyleSheetTag, getUnistyles, isKindOfStyleSheet } = require('./stylesheet')
const { extractVariants } = require('./variants')
const { REACT_NATIVE_COMPONENT_NAMES, REPLACE_WITH_UNISTYLES_PATHS, REPLACE_WITH_UNISTYLES_EXOTIC_PATHS } = require('./consts')
const { REACT_NATIVE_COMPONENT_NAMES, REPLACE_WITH_UNISTYLES_PATHS, REPLACE_WITH_UNISTYLES_EXOTIC_PATHS, NATIVE_COMPONENTS_PATHS } = require('./consts')
const { handleExoticImport } = require('./exotic')

module.exports = function ({ types: t }) {
Expand Down Expand Up @@ -109,6 +109,10 @@ module.exports = function ({ types: t }) {
})
}

if (importSource.includes('react-native/Libraries')) {
handleExoticImport(t, path, state, NATIVE_COMPONENTS_PATHS)
}

if (!state.file.forceProcessing && Array.isArray(state.opts.autoProcessImports)) {
state.file.forceProcessing = state.opts.autoProcessImports.includes(importSource)
}
Expand Down
12 changes: 12 additions & 0 deletions src/components/native/NativeText.native.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { TextProps } from 'react-native'
import { type ComponentType, createElement, forwardRef } from 'react'
import { createUnistylesElement } from '../../core'

// credits to @hirbod
const LeanText = forwardRef((props, ref) => {
return createElement('RCTText', { ...props, ref })
}) as ComponentType<TextProps>

LeanText.displayName = 'RCTText'

export const NativeText = createUnistylesElement(LeanText)
1 change: 1 addition & 0 deletions src/components/native/NativeText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Text } from './Text'
13 changes: 13 additions & 0 deletions src/components/native/NativeView.native.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { ViewProps } from 'react-native'
import { type ComponentType, createElement, forwardRef } from 'react'
import { createUnistylesElement } from '../../core'

// credits to @hirbod
const LeanView = forwardRef((props, ref) => {
return createElement('RCTView', { ...props, ref })
}) as ComponentType<ViewProps>

LeanView.displayName = 'RCTView'

// this will match default export from react-native
export default createUnistylesElement(LeanView)
3 changes: 3 additions & 0 deletions src/components/native/NativeView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { View } from './View'

export default View

0 comments on commit 2ea3bf4

Please sign in to comment.