From 1ae9f8829d3ce4c40c8169f8635fdb2eba6dc571 Mon Sep 17 00:00:00 2001 From: Jacek Pudysz Date: Mon, 27 Jan 2025 14:47:00 +0100 Subject: [PATCH] feat: add option to auto process root --- .../content/docs/v3/other/babel-plugin.mdx | 38 ++++++++++++++----- plugin/index.d.ts | 20 +++++----- plugin/index.js | 6 ++- src/components/native/Pressable.native.tsx | 4 +- src/core/createUnistylesElement.native.tsx | 4 +- src/core/createUnistylesImageBackground.tsx | 4 +- 6 files changed, 50 insertions(+), 26 deletions(-) diff --git a/docs/src/content/docs/v3/other/babel-plugin.mdx b/docs/src/content/docs/v3/other/babel-plugin.mdx index 70c38fd5..e0831c7b 100644 --- a/docs/src/content/docs/v3/other/babel-plugin.mdx +++ b/docs/src/content/docs/v3/other/babel-plugin.mdx @@ -194,21 +194,39 @@ By leveraging such scopes, we ensure support for any level of nesting! The Babel plugin comes with a few additional options to extend its usage. +:::caution +By default babel plugin will look for any `react-native-unistyles` import to start processing your file. +You can change this behaviour with options below: +::: + +#### `autoProcessRoot` + +If you want to process all your files, regardless of whether they include a `react-native-unistyles` import, you can set the `autoProcessRoot` option. + +```js +{ + autoProcessRoot: 'src' // or 'app', or any name of your root folder +} +``` + +Folder name will be resolved with `process.cwd()`. + #### `autoProcessImports` -By default babel plugin will look for any `react-native-unistyles` import to start processing your file. -However, in some cases you might want to process files that miss such import: -- ui-kits that aggregates Unistyles components -- monorepos that use Unistyles under absolute path like `@codemask/styles` +This configuration should be used when you want to process only files containing specific imports. +It can be useful for monorepos that use Unistyles with absolute paths, such as `@codemask/styles`. -If that's your case, you can configure the Babel plugin to process them. +```js +{ + autoProcessImports: ['@codemask/styles'] // whenever Babel encounters this import, it will process your file +} +``` #### `autoProcessPaths` -By default babel plugin will ignore `node_modules`. -However similar to `autoProcessImports`, you can configure it to process extra paths. - -Under these paths we will replace `react-native` imports with `react-native-unistyles` factories that will borrow components refs [read more](/v3/other/babel-plugin#3-component-factory-borrowing-ref). +This configuration is unrelated to the `autoProcessRoot` and `autoProcessImports` options and can be used alongside them. +By default, the Babel plugin ignores `node_modules`. However, you can extend these paths to attempt converting 3rd components into Unistyles compatible ones. +Within these paths, we will replace `react-native` imports with `react-native-unistyles` factories that borrow component refs. [Read more](/v3/other/babel-plugin#3-component-factory-borrowing-ref). Defaults to: @@ -228,7 +246,9 @@ You can apply any of the options above as follows: ```js title="babel.config.js" /** @type {import('react-native-unistyles/plugin').UnistylesPluginOptions} */ const unistylesPluginOptions = { + autoProcessRoot: 'src', autoProcessImports: ['@react-native-ui-kit', '@codemask/styles'], + autoProcessPaths: ['external-library/components'], debug: true, } diff --git a/plugin/index.d.ts b/plugin/index.d.ts index 4d78bd90..885af55f 100644 --- a/plugin/index.d.ts +++ b/plugin/index.d.ts @@ -1,18 +1,20 @@ export interface UnistylesPluginOptions { + /** + * Example: "src" or "apps/mobile" + * Add this option if some of your components don't have `react-native-unistyles` import. + * Babel plugin will automatically process all files under this root. + */ + autoProcessRoot?: string + /** - * By default babel plugin will look for any `react-native-unistyles` import to start processing your file. - * However, in some cases you might want to process files that miss such import: - * - ui-kits that aggregates Unistyles components - * - monorepos that use Unistyles under absolute path like `@codemask/styles` - * - * If that's your case, you can configure the Babel plugin to process them. + * Example: ['@codemask/styles'] + * Enable this option if you want to process only files containing specific imports. */ autoProcessImports?: string[] /** - * By default babel plugin will ignore `node_modules`. - * However similar to `autoProcessImports`, you can configure it to process extra paths. - * + * Example: ['external-library/components'] + * Enable this option to process some 3rd party components under `node_modules`. * Under these paths we will replace `react-native` imports with `react-native-unistyles` factories that will borrow components refs [read more](https://www.unistyl.es/v3/other/babel-plugin#3-component-factory-borrowing-ref). * * Defaults to: diff --git a/plugin/index.js b/plugin/index.js index 6b89d091..acdb6d42 100644 --- a/plugin/index.js +++ b/plugin/index.js @@ -48,14 +48,16 @@ module.exports = function ({ types: t }) { state.file.styleSheetLocalName = '' state.file.tagNumber = 0 state.reactNativeImports = {} - state.file.forceProcessing = false + state.file.forceProcessing = state.opts.autoProcessRoot + ? state.filename.includes(`${state.file.opts.root}/${state.opts.autoProcessRoot}/`) + : false }, exit(path, state) { if (isInsideNodeModules(state) && !state.file.replaceWithUnistyles) { return } - if (state.file.hasAnyUnistyle || state.file.hasVariants || state.file.replaceWithUnistyles) { + if (state.file.hasAnyUnistyle || state.file.hasVariants || state.file.replaceWithUnistyles || state.file.forceProcessing) { addUnistylesImport(t, path, state) } } diff --git a/src/components/native/Pressable.native.tsx b/src/components/native/Pressable.native.tsx index 239ac2a8..3534e2ca 100644 --- a/src/components/native/Pressable.native.tsx +++ b/src/components/native/Pressable.native.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, useEffect, useRef } from 'react' +import React, { forwardRef, useLayoutEffect, useRef } from 'react' import { Pressable as NativePressableReactNative } from 'react-native' import type { PressableProps as Props, View } from 'react-native' import { UnistylesShadowRegistry } from '../../specs' @@ -11,7 +11,7 @@ type PressableProps = Props & { export const Pressable = forwardRef(({ variants, style, ...props }, forwardedRef) => { const storedRef = useRef() - useEffect(() => { + useLayoutEffect(() => { return () => { if (storedRef.current) { // @ts-expect-error - this is hidden from TS diff --git a/src/core/createUnistylesElement.native.tsx b/src/core/createUnistylesElement.native.tsx index 8bc19ae1..ea43250d 100644 --- a/src/core/createUnistylesElement.native.tsx +++ b/src/core/createUnistylesElement.native.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from 'react' +import React, { useLayoutEffect, useRef } from 'react' import { UnistylesShadowRegistry } from '../specs' import { passForwardedRef } from './passForwardRef' import { maybeWarnAboutMultipleUnistyles } from './warn' @@ -19,7 +19,7 @@ const getNativeRef = (Component: any, ref: any) => { export const createUnistylesElement = (Component: any) => React.forwardRef((props, forwardedRef) => { const storedRef = useRef(null) - useEffect(() => { + useLayoutEffect(() => { return () => { if (storedRef.current) { // @ts-ignore diff --git a/src/core/createUnistylesImageBackground.tsx b/src/core/createUnistylesImageBackground.tsx index 3e25d087..10978595 100644 --- a/src/core/createUnistylesImageBackground.tsx +++ b/src/core/createUnistylesImageBackground.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from 'react' +import React, { useLayoutEffect, useRef } from 'react' import type { Image, ImageBackground, ImageBackgroundProps } from 'react-native' import { UnistylesShadowRegistry } from '../specs' import { passForwardedRef } from './passForwardRef' @@ -7,7 +7,7 @@ import { maybeWarnAboutMultipleUnistyles } from './warn' export const createUnistylesImageBackground = (Component: typeof ImageBackground) => React.forwardRef((props, forwardedRef) => { const storedImageRef = useRef(null) - useEffect(() => { + useLayoutEffect(() => { return () => { if (storedImageRef.current) { // @ts-ignore