From faa878df7e63905932d9e358b1884da4fd95a98c Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Tue, 5 May 2026 12:07:56 +0200 Subject: [PATCH 01/13] refactor: add import aliases and move vite to bundler/adapters --- packages/uniwind/build.config.ts | 14 ++++++++++++-- .../src/{ => bundler/adapters}/vite/index.d.ts | 0 .../src/{ => bundler/adapters}/vite/index.ts | 0 .../src/{ => bundler/adapters}/vite/vite.ts | 18 +++++++++--------- packages/uniwind/tsconfig.json | 9 +++++++++ 5 files changed, 30 insertions(+), 11 deletions(-) rename packages/uniwind/src/{ => bundler/adapters}/vite/index.d.ts (100%) rename packages/uniwind/src/{ => bundler/adapters}/vite/index.ts (100%) rename packages/uniwind/src/{ => bundler/adapters}/vite/vite.ts (86%) diff --git a/packages/uniwind/build.config.ts b/packages/uniwind/build.config.ts index 37b47c76..1c03d707 100644 --- a/packages/uniwind/build.config.ts +++ b/packages/uniwind/build.config.ts @@ -1,3 +1,4 @@ +import { fileURLToPath } from 'node:url' import { BuildConfig, defineBuildConfig } from 'unbuild' type Config = { @@ -7,6 +8,8 @@ type Config = { declaration?: boolean } +const srcPath = (path: string) => fileURLToPath(new URL(`./src/${path}`, import.meta.url)) + const getConfig = (config: Config) => [ { @@ -58,12 +61,12 @@ export default defineBuildConfig({ }, { builder: 'rollup', - input: './src/vite', + input: './src/bundler/adapters/vite', name: 'vite/index', }, { builder: 'mkdist', - input: './src/vite', + input: './src/bundler/adapters/vite', outDir: 'dist/vite', pattern: ['index.d.ts'], declaration: true, @@ -85,10 +88,17 @@ export default defineBuildConfig({ pattern: [ '**/*', '!metro/**', + '!bundler/adapters/vite/**', ], declaration: true, }), ], + alias: { + '@/css': srcPath('css'), + '@/css-visitor': srcPath('css-visitor'), + '@/metro': srcPath('metro'), + '@/utils': srcPath('utils'), + }, outDir: 'dist', clean: true, externals: [ diff --git a/packages/uniwind/src/vite/index.d.ts b/packages/uniwind/src/bundler/adapters/vite/index.d.ts similarity index 100% rename from packages/uniwind/src/vite/index.d.ts rename to packages/uniwind/src/bundler/adapters/vite/index.d.ts diff --git a/packages/uniwind/src/vite/index.ts b/packages/uniwind/src/bundler/adapters/vite/index.ts similarity index 100% rename from packages/uniwind/src/vite/index.ts rename to packages/uniwind/src/bundler/adapters/vite/index.ts diff --git a/packages/uniwind/src/vite/vite.ts b/packages/uniwind/src/bundler/adapters/vite/vite.ts similarity index 86% rename from packages/uniwind/src/vite/vite.ts rename to packages/uniwind/src/bundler/adapters/vite/vite.ts index 31267b8f..3d6b2c40 100644 --- a/packages/uniwind/src/vite/vite.ts +++ b/packages/uniwind/src/bundler/adapters/vite/vite.ts @@ -1,12 +1,12 @@ import { normalizePath } from '@tailwindcss/node' import path from 'path' import type { Plugin } from 'vite' -import { name as UNIWIND_PACKAGE_NAME } from '../../package.json' -import { buildCSS } from '../css' -import { UniwindCSSVisitor } from '../css-visitor' -import { uniq } from '../metro/utils' -import { buildDtsFile } from '../utils/buildDtsFile' -import { stringifyThemes } from '../utils/stringifyThemes' + +import { buildCSS } from '@/css' +import { UniwindCSSVisitor } from '@/css-visitor' +import { uniq } from '@/metro/utils' +import { buildDtsFile } from '@/utils/buildDtsFile' +import { stringifyThemes } from '@/utils/stringifyThemes' type UniwindConfig = { cssEntryFile: string @@ -56,7 +56,7 @@ export const uniwind = ({ }, }, optimizeDeps: { - exclude: [UNIWIND_PACKAGE_NAME, 'react-native'], + exclude: ['uniwind', 'react-native'], esbuildOptions: { plugins: [{ name: 'uniwind-esbuild-plugin', @@ -81,7 +81,7 @@ export const uniwind = ({ customResolver: { resolveId(_, importer) { // Check if import comes from uniwind - if (importer !== undefined && normalizePath(importer).includes(`${UNIWIND_PACKAGE_NAME}/dist`)) { + if (importer !== undefined && normalizePath(importer).includes('uniwind/dist')) { return this.resolve('react-native-web') } @@ -95,7 +95,7 @@ export const uniwind = ({ transform: (code, id) => { const normalizedId = normalizePath(id) - if (normalizedId.includes(`${UNIWIND_PACKAGE_NAME}/dist`) && normalizedId.includes('config/config.js')) { + if (normalizedId.includes('uniwind/dist') && normalizedId.includes('config/config.js')) { return { code: `${code}Uniwind.__reinit(() => ({}), ${stringifiedThemes})`, } diff --git a/packages/uniwind/tsconfig.json b/packages/uniwind/tsconfig.json index 7b18d357..b33863b0 100644 --- a/packages/uniwind/tsconfig.json +++ b/packages/uniwind/tsconfig.json @@ -9,6 +9,15 @@ "isolatedModules": true, "strict": true, "noUncheckedIndexedAccess": true, + "paths": { + "@/css": ["./src/css/index.ts"], + "@/css/*": ["./src/css/*"], + "@/css-visitor": ["./src/css-visitor/index.ts"], + "@/css-visitor/*": ["./src/css-visitor/*"], + "@/metro": ["./src/metro/index.ts"], + "@/metro/*": ["./src/metro/*"], + "@/utils/*": ["./src/utils/*"] + }, "moduleResolution": "Bundler", "module": "ESNext", "outDir": "dist", From 7b315a1e7415205d093bad243de88da5d72974c9 Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Wed, 6 May 2026 09:46:23 +0200 Subject: [PATCH 02/13] refactor: refactored bundler code --- packages/uniwind/build.config.ts | 13 +- packages/uniwind/jest.config.native.js | 1 + packages/uniwind/jest.config.web.js | 1 + .../{ => bundler/adapters}/metro/index.d.ts | 0 .../src/bundler/adapters/metro/index.ts | 1 + .../adapters/metro/metro.ts} | 29 ++--- .../adapters/metro/patches.ts} | 0 .../{ => bundler/adapters}/metro/resolvers.ts | 0 .../src/bundler/adapters/metro/transformer.ts | 82 +++++++++++++ .../uniwind/src/bundler/adapters/vite/vite.ts | 37 ++---- .../artifacts}/css/extraUtilities.ts | 2 +- .../src/{ => bundler/artifacts}/css/index.ts | 6 +- .../src/{ => bundler/artifacts}/css/insets.ts | 0 .../{ => bundler/artifacts}/css/overwrite.ts | 0 .../src/{ => bundler/artifacts}/css/themes.ts | 2 +- .../{ => bundler/artifacts}/css/variants.ts | 0 .../artifacts/dts.ts} | 7 +- packages/uniwind/src/bundler/config.ts | 79 ++++++++++++ .../src/bundler/css-compiler/compileCSS.ts | 15 +++ .../bundler/css-compiler/compileNativeCSS.ts | 36 ++++++ .../bundler/css-compiler/compileTailwind.ts | 25 ++++ .../src/bundler/css-compiler/compileWebCSS.ts | 11 ++ .../uniwind/src/bundler/css-compiler/index.ts | 1 + .../css-processor}/addMetaToStylesTemplate.ts | 8 +- .../css-processor}/color.ts | 2 +- .../bundler/css-processor/css-processor.ts | 0 .../css-processor}/css.ts | 4 +- .../css-processor}/functions.ts | 2 +- .../src/bundler/css-processor/index.ts | 3 + .../processor => bundler/css-processor}/mq.ts | 5 +- .../css-processor}/processor.ts | 5 +- .../processor => bundler/css-processor}/rn.ts | 4 +- .../css-processor}/serialize.ts | 4 +- .../{metro => bundler/css-processor}/types.ts | 17 +-- .../css-processor}/units.ts | 0 .../css-processor/utils.ts} | 0 .../css-processor}/var.ts | 0 .../css-visitor/function-visitor.ts | 0 .../src/{ => bundler}/css-visitor/index.ts | 0 .../{ => bundler}/css-visitor/rule-visitor.ts | 0 .../src/{ => bundler}/css-visitor/visitor.ts | 0 .../uniwind/src/{metro => bundler}/logger.ts | 0 packages/uniwind/src/bundler/types.ts | 15 +++ packages/uniwind/src/common/consts.ts | 22 ++++ packages/uniwind/src/components/web/rnw.ts | 2 +- .../uniwind/src/core/config/config.common.ts | 2 +- .../uniwind/src/core/config/config.native.ts | 2 +- packages/uniwind/src/core/config/config.ts | 2 +- packages/uniwind/src/core/listener.ts | 2 +- packages/uniwind/src/core/native/runtime.ts | 2 +- packages/uniwind/src/core/native/store.ts | 3 +- packages/uniwind/src/core/types.ts | 4 +- packages/uniwind/src/core/web/cssListener.ts | 2 +- .../uniwind/src/hoc/withUniwind.native.tsx | 2 +- .../hooks/useCSSVariable/useCSSVariable.ts | 2 +- packages/uniwind/src/hooks/useUniwind.ts | 2 +- packages/uniwind/src/index.ts | 3 +- packages/uniwind/src/metro/compileVirtual.ts | 80 ------------ packages/uniwind/src/metro/index.ts | 1 - packages/uniwind/src/metro/injectThemes.ts | 23 ---- .../uniwind/src/metro/metro-transformer.ts | 116 ------------------ packages/uniwind/src/metro/processor/index.ts | 1 - packages/uniwind/src/metro/utils/index.ts | 2 - packages/uniwind/src/types.ts | 23 ---- packages/uniwind/src/utils/stringifyThemes.ts | 1 - packages/uniwind/tests/e2e/global-setup.ts | 20 ++- packages/uniwind/tests/setup.native.ts | 19 +-- packages/uniwind/tsconfig.json | 9 +- 68 files changed, 371 insertions(+), 393 deletions(-) rename packages/uniwind/src/{ => bundler/adapters}/metro/index.d.ts (100%) create mode 100644 packages/uniwind/src/bundler/adapters/metro/index.ts rename packages/uniwind/src/{metro/withUniwindConfig.ts => bundler/adapters/metro/metro.ts} (62%) rename packages/uniwind/src/{metro/metro-css-patches.ts => bundler/adapters/metro/patches.ts} (100%) rename packages/uniwind/src/{ => bundler/adapters}/metro/resolvers.ts (100%) create mode 100644 packages/uniwind/src/bundler/adapters/metro/transformer.ts rename packages/uniwind/src/{ => bundler/artifacts}/css/extraUtilities.ts (94%) rename packages/uniwind/src/{ => bundler/artifacts}/css/index.ts (80%) rename packages/uniwind/src/{ => bundler/artifacts}/css/insets.ts (100%) rename packages/uniwind/src/{ => bundler/artifacts}/css/overwrite.ts (100%) rename packages/uniwind/src/{ => bundler/artifacts}/css/themes.ts (99%) rename packages/uniwind/src/{ => bundler/artifacts}/css/variants.ts (100%) rename packages/uniwind/src/{utils/buildDtsFile.ts => bundler/artifacts/dts.ts} (74%) create mode 100644 packages/uniwind/src/bundler/config.ts create mode 100644 packages/uniwind/src/bundler/css-compiler/compileCSS.ts create mode 100644 packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts create mode 100644 packages/uniwind/src/bundler/css-compiler/compileTailwind.ts create mode 100644 packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts create mode 100644 packages/uniwind/src/bundler/css-compiler/index.ts rename packages/uniwind/src/{metro => bundler/css-processor}/addMetaToStylesTemplate.ts (96%) rename packages/uniwind/src/{metro/processor => bundler/css-processor}/color.ts (98%) create mode 100644 packages/uniwind/src/bundler/css-processor/css-processor.ts rename packages/uniwind/src/{metro/processor => bundler/css-processor}/css.ts (99%) rename packages/uniwind/src/{metro/processor => bundler/css-processor}/functions.ts (99%) create mode 100644 packages/uniwind/src/bundler/css-processor/index.ts rename packages/uniwind/src/{metro/processor => bundler/css-processor}/mq.ts (94%) rename packages/uniwind/src/{metro/processor => bundler/css-processor}/processor.ts (99%) rename packages/uniwind/src/{metro/processor => bundler/css-processor}/rn.ts (99%) rename packages/uniwind/src/{metro/utils => bundler/css-processor}/serialize.ts (97%) rename packages/uniwind/src/{metro => bundler/css-processor}/types.ts (80%) rename packages/uniwind/src/{metro/processor => bundler/css-processor}/units.ts (100%) rename packages/uniwind/src/{metro/utils/common.ts => bundler/css-processor/utils.ts} (100%) rename packages/uniwind/src/{metro/processor => bundler/css-processor}/var.ts (100%) rename packages/uniwind/src/{ => bundler}/css-visitor/function-visitor.ts (100%) rename packages/uniwind/src/{ => bundler}/css-visitor/index.ts (100%) rename packages/uniwind/src/{ => bundler}/css-visitor/rule-visitor.ts (100%) rename packages/uniwind/src/{ => bundler}/css-visitor/visitor.ts (100%) rename packages/uniwind/src/{metro => bundler}/logger.ts (100%) create mode 100644 packages/uniwind/src/bundler/types.ts delete mode 100644 packages/uniwind/src/metro/compileVirtual.ts delete mode 100644 packages/uniwind/src/metro/index.ts delete mode 100644 packages/uniwind/src/metro/injectThemes.ts delete mode 100644 packages/uniwind/src/metro/metro-transformer.ts delete mode 100644 packages/uniwind/src/metro/processor/index.ts delete mode 100644 packages/uniwind/src/metro/utils/index.ts delete mode 100644 packages/uniwind/src/types.ts delete mode 100644 packages/uniwind/src/utils/stringifyThemes.ts diff --git a/packages/uniwind/build.config.ts b/packages/uniwind/build.config.ts index 1c03d707..9c0dc7a2 100644 --- a/packages/uniwind/build.config.ts +++ b/packages/uniwind/build.config.ts @@ -43,17 +43,17 @@ export default defineBuildConfig({ entries: [ { builder: 'rollup', - input: './src/metro', + input: './src/bundler/adapters/metro', name: 'metro/index', }, { builder: 'rollup', - input: './src/metro/metro-transformer.ts', - name: 'metro/metro-transformer', + input: './src/bundler/adapters/metro/transformer.ts', + name: 'metro/transformer', }, { builder: 'mkdist', - input: './src/metro', + input: './src/bundler/adapters/metro', outDir: 'dist/metro', pattern: ['index.d.ts'], declaration: true, @@ -88,16 +88,17 @@ export default defineBuildConfig({ pattern: [ '**/*', '!metro/**', + '!bundler/adapters/metro/**', '!bundler/adapters/vite/**', ], declaration: true, }), ], alias: { - '@/css': srcPath('css'), - '@/css-visitor': srcPath('css-visitor'), '@/metro': srcPath('metro'), '@/utils': srcPath('utils'), + '@/common': srcPath('common'), + '@/bundler': srcPath('bundler'), }, outDir: 'dist', clean: true, diff --git a/packages/uniwind/jest.config.native.js b/packages/uniwind/jest.config.native.js index 36ee34be..51c6651f 100644 --- a/packages/uniwind/jest.config.native.js +++ b/packages/uniwind/jest.config.native.js @@ -8,5 +8,6 @@ export default { ], moduleNameMapper: { '^react-native$': '/../../node_modules/react-native', + '^@/(.*)$': '/src/$1', }, } diff --git a/packages/uniwind/jest.config.web.js b/packages/uniwind/jest.config.web.js index 71aecc65..c6e013a6 100644 --- a/packages/uniwind/jest.config.web.js +++ b/packages/uniwind/jest.config.web.js @@ -9,6 +9,7 @@ export default { preset: 'ts-jest', moduleNameMapper: { '^react-native$': 'react-native-web', + '^@/(.*)$': '/src/$1', }, transformIgnorePatterns: [ 'node_modules/(?!(react-native-web)/)', diff --git a/packages/uniwind/src/metro/index.d.ts b/packages/uniwind/src/bundler/adapters/metro/index.d.ts similarity index 100% rename from packages/uniwind/src/metro/index.d.ts rename to packages/uniwind/src/bundler/adapters/metro/index.d.ts diff --git a/packages/uniwind/src/bundler/adapters/metro/index.ts b/packages/uniwind/src/bundler/adapters/metro/index.ts new file mode 100644 index 00000000..f3deb731 --- /dev/null +++ b/packages/uniwind/src/bundler/adapters/metro/index.ts @@ -0,0 +1 @@ +export * from './metro' diff --git a/packages/uniwind/src/metro/withUniwindConfig.ts b/packages/uniwind/src/bundler/adapters/metro/metro.ts similarity index 62% rename from packages/uniwind/src/metro/withUniwindConfig.ts rename to packages/uniwind/src/bundler/adapters/metro/metro.ts index a934f17a..ffa882c1 100644 --- a/packages/uniwind/src/metro/withUniwindConfig.ts +++ b/packages/uniwind/src/bundler/adapters/metro/metro.ts @@ -1,39 +1,24 @@ +import { UniwindBundlerConfig } from '@/bundler/config' +import type { UniwindConfig } from '@/bundler/types' +import { Platform } from '@/common/consts' import type { MetroConfig } from 'metro-config' -import { Platform } from '../common/consts' -import { cacheStore, patchMetroGraphToSupportUncachedModules } from './metro-css-patches' +import { cacheStore, patchMetroGraphToSupportUncachedModules } from './patches' import { nativeResolver, webResolver } from './resolvers' -import { UniwindConfig } from './types' -import { uniq } from './utils' export const withUniwindConfig = ( config: T, uniwindConfig: UniwindConfig, ): T => { - uniwindConfig.themes = uniq([ - 'light', - 'dark', - ...(uniwindConfig.extraThemes ?? []), - ]) - + const bundlerConfig = UniwindBundlerConfig.fromMetroConfig(uniwindConfig, Platform.Native) patchMetroGraphToSupportUncachedModules() - if (typeof uniwindConfig === 'undefined') { - throw new Error('Uniwind: You need to pass second parameter to withUniwindConfig') - } - - if (typeof uniwindConfig.cssEntryFile === 'undefined') { - throw new Error( - 'Uniwind: You need to pass css css entry file to withUniwindConfig, e.g. withUniwindConfig(config, { cssEntryFile: "./global.css" })', - ) - } - return { ...config, cacheStores: [cacheStore], - transformerPath: require.resolve('./metro-transformer.cjs'), + transformerPath: require.resolve('./transformer.cjs'), transformer: { ...config.transformer, - uniwind: uniwindConfig, + uniwind: bundlerConfig.toMetroConfig(), }, resolver: { ...config.resolver, diff --git a/packages/uniwind/src/metro/metro-css-patches.ts b/packages/uniwind/src/bundler/adapters/metro/patches.ts similarity index 100% rename from packages/uniwind/src/metro/metro-css-patches.ts rename to packages/uniwind/src/bundler/adapters/metro/patches.ts diff --git a/packages/uniwind/src/metro/resolvers.ts b/packages/uniwind/src/bundler/adapters/metro/resolvers.ts similarity index 100% rename from packages/uniwind/src/metro/resolvers.ts rename to packages/uniwind/src/bundler/adapters/metro/resolvers.ts diff --git a/packages/uniwind/src/bundler/adapters/metro/transformer.ts b/packages/uniwind/src/bundler/adapters/metro/transformer.ts new file mode 100644 index 00000000..21d78921 --- /dev/null +++ b/packages/uniwind/src/bundler/adapters/metro/transformer.ts @@ -0,0 +1,82 @@ +import { UniwindBundlerConfig } from '@/bundler/config' +import { compileCSS } from '@/bundler/css-compiler' +import { UniwindMetroConfig } from '@/bundler/types' +import { Platform } from '@/common/consts' +import type { JsTransformerConfig, JsTransformOptions } from 'metro-transform-worker' +import path from 'path' + +const cssArtifactPath = path.resolve(__dirname, '../../uniwind.css') + +let worker: typeof import('metro-transform-worker') + +try { + try { + const { unstable_transformerPath } = require('@expo/metro-config') as typeof import('@expo/metro-config') + + worker = require(unstable_transformerPath) + } catch { + worker = require('@expo/metro-config/build/transform-worker/transform-worker.js') + } +} catch { + worker = require('metro-transform-worker') +} + +export const transform = async ( + config: JsTransformerConfig & { + uniwind: UniwindMetroConfig + }, + projectRoot: string, + filePath: string, + data: Buffer, + options: JsTransformOptions, +) => { + const isCss = options.type !== 'asset' && path.join(process.cwd(), config.uniwind.cssEntryFile) === path.join(projectRoot, filePath) + + if (filePath.endsWith('/components/web/metro-injected.js')) { + const bundlerConfig = UniwindBundlerConfig.fromMetroConfig(config.uniwind, Platform.Web) + + data = Buffer.from( + [ + `import { Uniwind } from 'uniwind';`, + `Uniwind.__reinit(() => ({}), ${bundlerConfig.stringifiedThemes});`, + ].join(''), + 'utf-8', + ) + } + + if (!isCss) { + return worker.transform(config, projectRoot, filePath, data, options) + } + + const bundlerConfig = UniwindBundlerConfig.fromMetroConfig(config.uniwind, options.platform) + const virtualCode = await compileCSS(bundlerConfig) + const isWeb = bundlerConfig.platform === Platform.Web + + data = Buffer.from( + isWeb + ? virtualCode + : [ + `const { Uniwind } = require('uniwind');`, + `Uniwind.__reinit(rt => ${virtualCode}, ${bundlerConfig.stringifiedThemes});`, + ].join(''), + 'utf-8', + ) + + await bundlerConfig.generateArtifacts(cssArtifactPath) + const transform: any = await worker.transform( + config, + projectRoot, + `${filePath}${isWeb ? '' : '.js'}`, + data, + options, + ) + + transform.output[0].data.css ??= {} + transform.output[0].data.css.skipCache = true + + if (!isWeb) { + transform.output[0].data.css.code = '' + } + + return transform +} diff --git a/packages/uniwind/src/bundler/adapters/vite/vite.ts b/packages/uniwind/src/bundler/adapters/vite/vite.ts index 3d6b2c40..cd0de2ec 100644 --- a/packages/uniwind/src/bundler/adapters/vite/vite.ts +++ b/packages/uniwind/src/bundler/adapters/vite/vite.ts @@ -2,17 +2,8 @@ import { normalizePath } from '@tailwindcss/node' import path from 'path' import type { Plugin } from 'vite' -import { buildCSS } from '@/css' -import { UniwindCSSVisitor } from '@/css-visitor' -import { uniq } from '@/metro/utils' -import { buildDtsFile } from '@/utils/buildDtsFile' -import { stringifyThemes } from '@/utils/stringifyThemes' - -type UniwindConfig = { - cssEntryFile: string - extraThemes?: Array - dtsFile?: string -} +import { UniwindBundlerConfig } from '@/bundler/config' +import type { UniwindConfig } from '@/bundler/types' const dirname = typeof __dirname !== 'undefined' ? __dirname : import.meta.dirname const componentPath = path.resolve( @@ -23,18 +14,10 @@ const styleSheetPath = path.resolve( dirname, '../module/components/web/createOrderedCSSStyleSheet.js', ) +const cssArtifactPath = path.resolve(dirname, '../../uniwind.css') -export const uniwind = ({ - cssEntryFile, - extraThemes, - dtsFile = 'uniwind-types.d.ts', -}: UniwindConfig): Plugin => { - const themes = uniq([ - 'light', - 'dark', - ...(extraThemes ?? []), - ]) - const stringifiedThemes = stringifyThemes(themes) +export const uniwind = (config: UniwindConfig): Plugin => { + const bundlerConfig = UniwindBundlerConfig.fromViteConfig(config) return { name: 'uniwind', @@ -52,7 +35,7 @@ export const uniwind = ({ css: { transformer: 'lightningcss', lightningcss: { - visitor: new UniwindCSSVisitor(themes), + visitor: bundlerConfig.cssVisitor, }, }, optimizeDeps: { @@ -97,17 +80,15 @@ export const uniwind = ({ if (normalizedId.includes('uniwind/dist') && normalizedId.includes('config/config.js')) { return { - code: `${code}Uniwind.__reinit(() => ({}), ${stringifiedThemes})`, + code: `${code}Uniwind.__reinit(() => ({}), ${bundlerConfig.stringifiedThemes})`, } } }, buildStart: async () => { - await buildCSS(themes, cssEntryFile) - buildDtsFile(dtsFile, stringifiedThemes) + await bundlerConfig.generateArtifacts(cssArtifactPath) }, generateBundle: async () => { - await buildCSS(themes, cssEntryFile) - buildDtsFile(dtsFile, stringifiedThemes) + await bundlerConfig.generateArtifacts(cssArtifactPath) }, } } diff --git a/packages/uniwind/src/css/extraUtilities.ts b/packages/uniwind/src/bundler/artifacts/css/extraUtilities.ts similarity index 94% rename from packages/uniwind/src/css/extraUtilities.ts rename to packages/uniwind/src/bundler/artifacts/css/extraUtilities.ts index 19cbae5d..f705d710 100644 --- a/packages/uniwind/src/css/extraUtilities.ts +++ b/packages/uniwind/src/bundler/artifacts/css/extraUtilities.ts @@ -1,4 +1,4 @@ -import { RNStyle } from '../core/types' +import { RNStyle } from '../../../core/types' const toKebabCase = (str: string) => str.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`) diff --git a/packages/uniwind/src/css/index.ts b/packages/uniwind/src/bundler/artifacts/css/index.ts similarity index 80% rename from packages/uniwind/src/css/index.ts rename to packages/uniwind/src/bundler/artifacts/css/index.ts index b613e35b..420c421c 100644 --- a/packages/uniwind/src/css/index.ts +++ b/packages/uniwind/src/bundler/artifacts/css/index.ts @@ -1,16 +1,12 @@ import fs from 'fs' -import path from 'path' import { EXTRA_UTILITIES_CSS } from './extraUtilities' import { INSETS_CSS } from './insets' import { OVERWRITE_CSS } from './overwrite' import { generateCSSForThemes } from './themes' import { VARIANTS_CSS } from './variants' -const dirname = typeof __dirname !== 'undefined' ? __dirname : import.meta.dirname - -export const buildCSS = async (themes: Array, input: string) => { +export const buildCSS = async (themes: Array, input: string, cssFilePath: string) => { const themesCSS = await generateCSSForThemes(themes, input) - const cssFilePath = path.join(dirname, '../../uniwind.css') const oldCSSFile = fs.existsSync(cssFilePath) ? fs.readFileSync(cssFilePath, 'utf-8') : '' diff --git a/packages/uniwind/src/css/insets.ts b/packages/uniwind/src/bundler/artifacts/css/insets.ts similarity index 100% rename from packages/uniwind/src/css/insets.ts rename to packages/uniwind/src/bundler/artifacts/css/insets.ts diff --git a/packages/uniwind/src/css/overwrite.ts b/packages/uniwind/src/bundler/artifacts/css/overwrite.ts similarity index 100% rename from packages/uniwind/src/css/overwrite.ts rename to packages/uniwind/src/bundler/artifacts/css/overwrite.ts diff --git a/packages/uniwind/src/css/themes.ts b/packages/uniwind/src/bundler/artifacts/css/themes.ts similarity index 99% rename from packages/uniwind/src/css/themes.ts rename to packages/uniwind/src/bundler/artifacts/css/themes.ts index c57b77b9..c04ab2d1 100644 --- a/packages/uniwind/src/css/themes.ts +++ b/packages/uniwind/src/bundler/artifacts/css/themes.ts @@ -2,7 +2,7 @@ import { compile } from '@tailwindcss/node' import fs from 'fs' import { transform } from 'lightningcss' import path from 'path' -import { Logger } from '../metro/logger' +import { Logger } from '../../logger' const readFileSafe = (filePath: string) => { try { diff --git a/packages/uniwind/src/css/variants.ts b/packages/uniwind/src/bundler/artifacts/css/variants.ts similarity index 100% rename from packages/uniwind/src/css/variants.ts rename to packages/uniwind/src/bundler/artifacts/css/variants.ts diff --git a/packages/uniwind/src/utils/buildDtsFile.ts b/packages/uniwind/src/bundler/artifacts/dts.ts similarity index 74% rename from packages/uniwind/src/utils/buildDtsFile.ts rename to packages/uniwind/src/bundler/artifacts/dts.ts index 448852e3..2df073f4 100644 --- a/packages/uniwind/src/utils/buildDtsFile.ts +++ b/packages/uniwind/src/bundler/artifacts/dts.ts @@ -1,15 +1,14 @@ import fs from 'fs' -import { name } from '../../package.json' export const buildDtsFile = (dtsPath: string, stringifiedThemes: string) => { const oldDtsContent = fs.existsSync(dtsPath) ? fs.readFileSync(dtsPath, 'utf-8') : '' const dtsContent = [ - `// NOTE: This file is generated by ${name} and it should not be edited manually.`, - `/// `, + `// NOTE: This file is generated by uniwind and it should not be edited manually.`, + `/// `, '', - `declare module '${name}' {`, + `declare module 'uniwind' {`, ` export interface UniwindConfig {`, ` themes: readonly ${stringifiedThemes}`, ` }`, diff --git a/packages/uniwind/src/bundler/config.ts b/packages/uniwind/src/bundler/config.ts new file mode 100644 index 00000000..75314f3b --- /dev/null +++ b/packages/uniwind/src/bundler/config.ts @@ -0,0 +1,79 @@ +import { buildCSS } from '@/bundler/artifacts/css' +import { buildDtsFile } from '@/bundler/artifacts/dts' +import { UniwindCSSVisitor } from '@/bundler/css-visitor' +import type { UniwindConfig, UniwindMetroConfig } from '@/bundler/types' +import { Platform } from '@/common/consts' +import path from 'path' + +export class UniwindBundlerConfig { + static fromMetroConfig(config: UniwindMetroConfig, platform: string | null | undefined) { + const getPlatform = () => { + if (!config.isTV) { + return platform as Platform + } + + if (platform === Platform.Android) { + return Platform.AndroidTV + } + + if (platform === Platform.iOS) { + return Platform.AppleTV + } + + throw new Error(`Platform ${platform} not supported`) + } + + if (typeof config === 'undefined') { + throw new Error('Uniwind: You need to pass second parameter to withUniwindConfig') + } + + if (typeof config.cssEntryFile === 'undefined') { + throw new Error( + 'Uniwind: You need to pass css css entry file to withUniwindConfig, e.g. withUniwindConfig(config, { cssEntryFile: "./global.css" })', + ) + } + + return new UniwindBundlerConfig(config, getPlatform()) + } + + static fromViteConfig(config: UniwindConfig) { + return new UniwindBundlerConfig(config, Platform.Web) + } + + constructor(private readonly config: UniwindMetroConfig, readonly platform: Platform) {} + + get cssPath() { + return path.join(process.cwd(), this.config.cssEntryFile) + } + + get themes() { + return Array.from( + new Set([ + 'light', + 'dark', + ...this.config.extraThemes ?? [], + ]), + ) + } + + get cssVisitor() { + return new UniwindCSSVisitor(this.themes) + } + + get polyfills() { + return this.config.polyfills + } + + get stringifiedThemes() { + return `[${this.themes.map((theme) => `'${theme}'`).join(', ')}]` + } + + toMetroConfig() { + return this.config + } + + async generateArtifacts(cssArtifactPath: string) { + await buildCSS(this.themes, this.config.cssEntryFile, cssArtifactPath) + buildDtsFile(this.config.dtsFile ?? 'uniwind-types.d.ts', this.stringifiedThemes) + } +} diff --git a/packages/uniwind/src/bundler/css-compiler/compileCSS.ts b/packages/uniwind/src/bundler/css-compiler/compileCSS.ts new file mode 100644 index 00000000..8d51a4f3 --- /dev/null +++ b/packages/uniwind/src/bundler/css-compiler/compileCSS.ts @@ -0,0 +1,15 @@ +import { Platform } from '@/common/consts' +import { UniwindBundlerConfig } from '../config' +import { compileNativeCSS } from './compileNativeCSS' +import { compileTailwind } from './compileTailwind' +import { compileWebCSS } from './compileWebCSS' + +export const compileCSS = async (bundlerConfig: UniwindBundlerConfig) => { + const tailwindCSS = await compileTailwind(bundlerConfig) + + if (bundlerConfig.platform === Platform.Web) { + return compileWebCSS(bundlerConfig, tailwindCSS) + } + + return compileNativeCSS(bundlerConfig, tailwindCSS) +} diff --git a/packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts b/packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts new file mode 100644 index 00000000..1fc2acc9 --- /dev/null +++ b/packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts @@ -0,0 +1,36 @@ +import { UniwindBundlerConfig } from '../config' +import { addMetaToStylesTemplate, ProcessorBuilder, serializeJSObject } from '../css-processor' + +export const compileNativeCSS = (bundlerConfig: UniwindBundlerConfig, tailwindCSS: string) => { + const Processor = new ProcessorBuilder(bundlerConfig.themes, bundlerConfig.polyfills) + + Processor.transform(tailwindCSS) + + const stylesheet = serializeJSObject( + addMetaToStylesTemplate(Processor, bundlerConfig.platform), + (key, value) => `"${key}": ${value}`, + ) + const vars = serializeJSObject( + Processor.vars, + (key, value) => `get "${key}"() { return ${value} }`, + ) + const scopedVars = Object.fromEntries( + Object.entries(Processor.scopedVars) + .map(([scopedVarsName, scopedVars]) => [ + scopedVarsName, + serializeJSObject(scopedVars, (key, value) => `get "${key}"() { return ${value} }`), + ]), + ) + const serializedScopedVars = Object.entries(scopedVars) + .map(([scopedVarsName, scopedVars]) => `"${scopedVarsName}": ({ ${scopedVars} }),`) + .join('') + const currentColorVar = `get currentColor() { return rt.colorScheme === 'dark' ? '#ffffff' : '#000000' },` + + return [ + '({', + `scopedVars: ({ ${serializedScopedVars} }),`, + `vars: ({ ${currentColorVar} ${vars} }),`, + `stylesheet: ({ ${stylesheet} }),`, + '})', + ].join('') +} diff --git a/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts b/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts new file mode 100644 index 00000000..0cd27413 --- /dev/null +++ b/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts @@ -0,0 +1,25 @@ +import { compile } from '@tailwindcss/node' +import { Scanner } from '@tailwindcss/oxide' +import fs from 'fs' +import path from 'path' +import { UniwindBundlerConfig } from '../config' + +export const compileTailwind = async (bundlerConfig: UniwindBundlerConfig) => { + const css = fs.readFileSync(bundlerConfig.cssPath, 'utf-8') + const compiler = await compile(css, { + base: path.dirname(bundlerConfig.cssPath), + onDependency: () => void 0, + }) + const scanner = new Scanner({ + sources: [ + ...compiler.sources, + { + negated: false, + pattern: '**/*', + base: path.dirname(bundlerConfig.cssPath), + }, + ], + }) + + return compiler.build(scanner.scan()) +} diff --git a/packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts b/packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts new file mode 100644 index 00000000..b7d791a2 --- /dev/null +++ b/packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts @@ -0,0 +1,11 @@ +import { transform } from 'lightningcss' +import { UniwindBundlerConfig } from '../config' +import { UniwindCSSVisitor } from '../css-visitor' + +export const compileWebCSS = (bundlerConfig: UniwindBundlerConfig, tailwindCSS: string) => { + return transform({ + code: Buffer.from(tailwindCSS), + filename: 'uniwind.css', + visitor: new UniwindCSSVisitor(bundlerConfig.themes), + }).code.toString() +} diff --git a/packages/uniwind/src/bundler/css-compiler/index.ts b/packages/uniwind/src/bundler/css-compiler/index.ts new file mode 100644 index 00000000..baa2272c --- /dev/null +++ b/packages/uniwind/src/bundler/css-compiler/index.ts @@ -0,0 +1 @@ +export * from './compileCSS' diff --git a/packages/uniwind/src/metro/addMetaToStylesTemplate.ts b/packages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.ts similarity index 96% rename from packages/uniwind/src/metro/addMetaToStylesTemplate.ts rename to packages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.ts index 2a7de792..d7662c58 100644 --- a/packages/uniwind/src/metro/addMetaToStylesTemplate.ts +++ b/packages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.ts @@ -1,9 +1,9 @@ -import { Platform } from '../common/consts' -import { isDefined } from '../common/utils' -import { StyleDependency } from '../types' +import { Platform, StyleDependency } from '@/common/consts' +import { isDefined } from '@/common/utils' import { ProcessorBuilder } from './processor' +import { serialize } from './serialize' import { StyleSheetTemplate } from './types' -import { serialize, toCamelCase } from './utils' +import { toCamelCase } from './utils' const extractVarsFromString = (value: string) => { const thisIndexes = [...value.matchAll(/this\[/g)].map(m => m.index) diff --git a/packages/uniwind/src/metro/processor/color.ts b/packages/uniwind/src/bundler/css-processor/color.ts similarity index 98% rename from packages/uniwind/src/metro/processor/color.ts rename to packages/uniwind/src/bundler/css-processor/color.ts index b0eda753..7033d1af 100644 --- a/packages/uniwind/src/metro/processor/color.ts +++ b/packages/uniwind/src/bundler/css-processor/color.ts @@ -1,8 +1,8 @@ import { Color as ColorType, converter, formatHex, formatHex8, parse } from 'culori' import { CssColor, UnresolvedColor } from 'lightningcss' import { Logger } from '../logger' -import { pipe } from '../utils' import type { ProcessorBuilder } from './processor' +import { pipe } from './utils' export class Color { private toRgb = converter('rgb') diff --git a/packages/uniwind/src/bundler/css-processor/css-processor.ts b/packages/uniwind/src/bundler/css-processor/css-processor.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/uniwind/src/metro/processor/css.ts b/packages/uniwind/src/bundler/css-processor/css.ts similarity index 99% rename from packages/uniwind/src/metro/processor/css.ts rename to packages/uniwind/src/bundler/css-processor/css.ts index 6e3d7dfb..fbff192c 100644 --- a/packages/uniwind/src/metro/processor/css.ts +++ b/packages/uniwind/src/bundler/css-processor/css.ts @@ -1,9 +1,9 @@ import { OverflowKeyword } from 'lightningcss' import { isDefined } from '../../common/utils' import { Logger } from '../logger' -import { DeclarationValues } from '../types' -import { deepEqual, pipe, roundToPrecision, shouldBeSerialized } from '../utils' import type { ProcessorBuilder } from './processor' +import { DeclarationValues } from './types' +import { deepEqual, pipe, roundToPrecision, shouldBeSerialized } from './utils' export class CSS { private readonly logger = new Logger('CSS') diff --git a/packages/uniwind/src/metro/processor/functions.ts b/packages/uniwind/src/bundler/css-processor/functions.ts similarity index 99% rename from packages/uniwind/src/metro/processor/functions.ts rename to packages/uniwind/src/bundler/css-processor/functions.ts index f27233d0..c895dc6b 100644 --- a/packages/uniwind/src/metro/processor/functions.ts +++ b/packages/uniwind/src/bundler/css-processor/functions.ts @@ -1,7 +1,7 @@ import { CalcFor_DimensionPercentageFor_LengthValue, CalcFor_Length, CssColor, Function as FunctionType } from 'lightningcss' import { Logger } from '../logger' -import { pipe } from '../utils' import type { ProcessorBuilder } from './processor' +import { pipe } from './utils' export class Functions { private readonly logger = new Logger('Functions') diff --git a/packages/uniwind/src/bundler/css-processor/index.ts b/packages/uniwind/src/bundler/css-processor/index.ts new file mode 100644 index 00000000..c2abf4c9 --- /dev/null +++ b/packages/uniwind/src/bundler/css-processor/index.ts @@ -0,0 +1,3 @@ +export * from './addMetaToStylesTemplate' +export * from './processor' +export * from './serialize' diff --git a/packages/uniwind/src/metro/processor/mq.ts b/packages/uniwind/src/bundler/css-processor/mq.ts similarity index 94% rename from packages/uniwind/src/metro/processor/mq.ts rename to packages/uniwind/src/bundler/css-processor/mq.ts index d3d8f312..c06dc94e 100644 --- a/packages/uniwind/src/metro/processor/mq.ts +++ b/packages/uniwind/src/bundler/css-processor/mq.ts @@ -1,8 +1,7 @@ +import { ColorScheme, Orientation, Platform } from '@/common/consts' import { MediaQuery, QueryFeatureFor_MediaFeatureId } from 'lightningcss' -import { Platform } from '../../common/consts' -import { ColorScheme, Orientation } from '../../types' -import { MediaQueryResolver } from '../types' import type { ProcessorBuilder } from './processor' +import { MediaQueryResolver } from './types' export class MQ { constructor(private readonly Processor: ProcessorBuilder) {} diff --git a/packages/uniwind/src/metro/processor/processor.ts b/packages/uniwind/src/bundler/css-processor/processor.ts similarity index 99% rename from packages/uniwind/src/metro/processor/processor.ts rename to packages/uniwind/src/bundler/css-processor/processor.ts index a7f65661..c5850780 100644 --- a/packages/uniwind/src/metro/processor/processor.ts +++ b/packages/uniwind/src/bundler/css-processor/processor.ts @@ -1,11 +1,12 @@ +import { UNIWIND_PLATFORM_VARIABLES, UNIWIND_THEME_VARIABLES } from '@/common/consts' import { Declaration, MediaQuery, Rule, transform } from 'lightningcss' -import { UNIWIND_PLATFORM_VARIABLES, UNIWIND_THEME_VARIABLES } from '../../common/consts' -import { Polyfills, ProcessMetaValues } from '../types' +import { Polyfills } from '../types' import { Color } from './color' import { CSS } from './css' import { Functions } from './functions' import { MQ } from './mq' import { RN } from './rn' +import { ProcessMetaValues } from './types' import { Units } from './units' import { Var } from './var' diff --git a/packages/uniwind/src/metro/processor/rn.ts b/packages/uniwind/src/bundler/css-processor/rn.ts similarity index 99% rename from packages/uniwind/src/metro/processor/rn.ts rename to packages/uniwind/src/bundler/css-processor/rn.ts index 80e42242..7785eedb 100644 --- a/packages/uniwind/src/metro/processor/rn.ts +++ b/packages/uniwind/src/bundler/css-processor/rn.ts @@ -1,6 +1,6 @@ -import { isDefined } from '../../common/utils' -import { addMissingSpaces, pipe, removeKeys, toCamelCase } from '../utils' +import { isDefined } from '@/common/utils' import type { ProcessorBuilder } from './processor' +import { addMissingSpaces, pipe, removeKeys, toCamelCase } from './utils' const cssToRNMap: Record Record> = { backgroundSize: value => { diff --git a/packages/uniwind/src/metro/utils/serialize.ts b/packages/uniwind/src/bundler/css-processor/serialize.ts similarity index 97% rename from packages/uniwind/src/metro/utils/serialize.ts rename to packages/uniwind/src/bundler/css-processor/serialize.ts index 9af6e6ba..9a02722c 100644 --- a/packages/uniwind/src/metro/utils/serialize.ts +++ b/packages/uniwind/src/bundler/css-processor/serialize.ts @@ -1,5 +1,5 @@ -import { Logger } from '../logger' -import { addMissingSpaces, isNumber, isValidJSValue, pipe, roundToPrecision, smartSplit } from './common' +import { Logger } from '@/bundler/logger' +import { addMissingSpaces, isNumber, isValidJSValue, pipe, roundToPrecision, smartSplit } from './utils' const parseStringValue = (value: string) => { if (isValidJSValue(value)) { diff --git a/packages/uniwind/src/metro/types.ts b/packages/uniwind/src/bundler/css-processor/types.ts similarity index 80% rename from packages/uniwind/src/metro/types.ts rename to packages/uniwind/src/bundler/css-processor/types.ts index 1da2fb57..50846300 100644 --- a/packages/uniwind/src/metro/types.ts +++ b/packages/uniwind/src/bundler/css-processor/types.ts @@ -1,3 +1,4 @@ +import { ColorScheme, Orientation, Platform } from '@/common/consts' import type { AbsoluteFontWeight, Declaration, @@ -11,22 +12,6 @@ import type { TokenOrValue, UnresolvedColor, } from 'lightningcss' -import { Platform } from '../common/consts' -import { ColorScheme, Orientation } from '../types' - -export type Polyfills = { - rem?: number -} - -export type UniwindConfig = { - cssEntryFile: string - themes: Array - extraThemes?: Array - dtsFile?: string - polyfills?: Polyfills - debug?: boolean - isTV?: boolean -} export type MediaQueryResolver = { maxWidth: any diff --git a/packages/uniwind/src/metro/processor/units.ts b/packages/uniwind/src/bundler/css-processor/units.ts similarity index 100% rename from packages/uniwind/src/metro/processor/units.ts rename to packages/uniwind/src/bundler/css-processor/units.ts diff --git a/packages/uniwind/src/metro/utils/common.ts b/packages/uniwind/src/bundler/css-processor/utils.ts similarity index 100% rename from packages/uniwind/src/metro/utils/common.ts rename to packages/uniwind/src/bundler/css-processor/utils.ts diff --git a/packages/uniwind/src/metro/processor/var.ts b/packages/uniwind/src/bundler/css-processor/var.ts similarity index 100% rename from packages/uniwind/src/metro/processor/var.ts rename to packages/uniwind/src/bundler/css-processor/var.ts diff --git a/packages/uniwind/src/css-visitor/function-visitor.ts b/packages/uniwind/src/bundler/css-visitor/function-visitor.ts similarity index 100% rename from packages/uniwind/src/css-visitor/function-visitor.ts rename to packages/uniwind/src/bundler/css-visitor/function-visitor.ts diff --git a/packages/uniwind/src/css-visitor/index.ts b/packages/uniwind/src/bundler/css-visitor/index.ts similarity index 100% rename from packages/uniwind/src/css-visitor/index.ts rename to packages/uniwind/src/bundler/css-visitor/index.ts diff --git a/packages/uniwind/src/css-visitor/rule-visitor.ts b/packages/uniwind/src/bundler/css-visitor/rule-visitor.ts similarity index 100% rename from packages/uniwind/src/css-visitor/rule-visitor.ts rename to packages/uniwind/src/bundler/css-visitor/rule-visitor.ts diff --git a/packages/uniwind/src/css-visitor/visitor.ts b/packages/uniwind/src/bundler/css-visitor/visitor.ts similarity index 100% rename from packages/uniwind/src/css-visitor/visitor.ts rename to packages/uniwind/src/bundler/css-visitor/visitor.ts diff --git a/packages/uniwind/src/metro/logger.ts b/packages/uniwind/src/bundler/logger.ts similarity index 100% rename from packages/uniwind/src/metro/logger.ts rename to packages/uniwind/src/bundler/logger.ts diff --git a/packages/uniwind/src/bundler/types.ts b/packages/uniwind/src/bundler/types.ts new file mode 100644 index 00000000..704c7e60 --- /dev/null +++ b/packages/uniwind/src/bundler/types.ts @@ -0,0 +1,15 @@ +export type UniwindConfig = { + cssEntryFile: string + extraThemes?: Array + dtsFile?: string +} + +export type Polyfills = { + rem?: number +} + +export type UniwindMetroConfig = UniwindConfig & { + polyfills?: Polyfills + debug?: boolean + isTV?: boolean +} diff --git a/packages/uniwind/src/common/consts.ts b/packages/uniwind/src/common/consts.ts index 2d3efe00..cb1c113e 100644 --- a/packages/uniwind/src/common/consts.ts +++ b/packages/uniwind/src/common/consts.ts @@ -10,3 +10,25 @@ export const enum Platform { export const UNIWIND_PLATFORM_VARIABLES = '__uniwind-platform-' export const UNIWIND_THEME_VARIABLES = '__uniwind-theme-' + +export enum StyleDependency { + ColorScheme = 1, + Theme = 2, + Dimensions = 3, + Orientation = 4, + Insets = 5, + FontScale = 6, + Rtl = 7, + AdaptiveThemes = 8, + Variables = 9, +} + +export const enum Orientation { + Portrait = 'portrait', + Landscape = 'landscape', +} + +export const enum ColorScheme { + Light = 'light', + Dark = 'dark', +} diff --git a/packages/uniwind/src/components/web/rnw.ts b/packages/uniwind/src/components/web/rnw.ts index c4faad46..d1f821c1 100644 --- a/packages/uniwind/src/components/web/rnw.ts +++ b/packages/uniwind/src/components/web/rnw.ts @@ -1,6 +1,6 @@ +import { StyleDependency } from '../../common/consts' import { Uniwind } from '../../core' import { UniwindListener } from '../../core/listener' -import { StyleDependency } from '../../types' import './metro-injected' type UniwindWithThemes = { diff --git a/packages/uniwind/src/core/config/config.common.ts b/packages/uniwind/src/core/config/config.common.ts index 3cc1fc5d..897adb26 100644 --- a/packages/uniwind/src/core/config/config.common.ts +++ b/packages/uniwind/src/core/config/config.common.ts @@ -1,6 +1,6 @@ import { Appearance, Insets, Platform } from 'react-native' +import { ColorScheme, StyleDependency } from '../../common/consts' import { GetCSSVariable, getCSSVariable } from '../../hooks/useCSSVariable/useCSSVariable' -import { ColorScheme, StyleDependency } from '../../types' import { UniwindListener } from '../listener' import { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types' diff --git a/packages/uniwind/src/core/config/config.native.ts b/packages/uniwind/src/core/config/config.native.ts index 29d91d62..a5eaef78 100644 --- a/packages/uniwind/src/core/config/config.native.ts +++ b/packages/uniwind/src/core/config/config.native.ts @@ -1,6 +1,6 @@ import { formatHex, formatHex8, parse } from 'culori' import { Insets } from 'react-native' -import { StyleDependency } from '../../types' +import { StyleDependency } from '../../common/consts' import { UniwindListener } from '../listener' import { Logger } from '../logger' import { UniwindStore } from '../native' diff --git a/packages/uniwind/src/core/config/config.ts b/packages/uniwind/src/core/config/config.ts index e2b21f42..bda1e851 100644 --- a/packages/uniwind/src/core/config/config.ts +++ b/packages/uniwind/src/core/config/config.ts @@ -1,5 +1,5 @@ +import { StyleDependency } from '../../common/consts' import { arrayEquals } from '../../common/utils' -import { StyleDependency } from '../../types' import { UniwindListener } from '../listener' import { Logger } from '../logger' import { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types' diff --git a/packages/uniwind/src/core/listener.ts b/packages/uniwind/src/core/listener.ts index ef0083a2..cd9794e6 100644 --- a/packages/uniwind/src/core/listener.ts +++ b/packages/uniwind/src/core/listener.ts @@ -1,4 +1,4 @@ -import { StyleDependency } from '../types' +import { StyleDependency } from '../common/consts' type SubscribeOptions = { once?: boolean diff --git a/packages/uniwind/src/core/native/runtime.ts b/packages/uniwind/src/core/native/runtime.ts index ebeb1a05..9ab99de7 100644 --- a/packages/uniwind/src/core/native/runtime.ts +++ b/packages/uniwind/src/core/native/runtime.ts @@ -1,5 +1,5 @@ import { Appearance, Dimensions, I18nManager, PixelRatio, StyleSheet } from 'react-native' -import { ColorScheme, Orientation } from '../../types' +import { ColorScheme, Orientation } from '../../common/consts' import type { UniwindRuntime as UniwindRuntimeType } from '../types' import { colorMix, lightDark, parseColor } from './native-utils' diff --git a/packages/uniwind/src/core/native/store.ts b/packages/uniwind/src/core/native/store.ts index 2e811877..b334f6a9 100644 --- a/packages/uniwind/src/core/native/store.ts +++ b/packages/uniwind/src/core/native/store.ts @@ -1,6 +1,5 @@ import { Dimensions, Platform } from 'react-native' -import { Platform as UniwindPlatform, UNIWIND_PLATFORM_VARIABLES, UNIWIND_THEME_VARIABLES } from '../../common/consts' -import { Orientation, StyleDependency } from '../../types' +import { Orientation, Platform as UniwindPlatform, StyleDependency, UNIWIND_PLATFORM_VARIABLES, UNIWIND_THEME_VARIABLES } from '../../common/consts' import { UniwindListener } from '../listener' import { ComponentState, GenerateStyleSheetsCallback, RNStyle, Style, StyleSheets, ThemeName, UniwindContextType } from '../types' import { cloneWithAccessors } from './native-utils' diff --git a/packages/uniwind/src/core/types.ts b/packages/uniwind/src/core/types.ts index 579093ec..467e33f2 100644 --- a/packages/uniwind/src/core/types.ts +++ b/packages/uniwind/src/core/types.ts @@ -1,6 +1,6 @@ import React from 'react' import type { ImageStyle, StyleProp, TextStyle, ViewStyle } from 'react-native' -import { ColorScheme, Orientation, StyleDependency, UniwindConfig } from '../types' +import { ColorScheme, Orientation, StyleDependency } from '../common/consts' import type { UniwindContext } from './context' export type Style = { @@ -30,6 +30,8 @@ export type GenerateStyleSheetsCallback = (rt: UniwindRuntime) => { scopedVars: Partial>> } +export interface UniwindConfig {} + type UserThemes = UniwindConfig extends { themes: infer T extends readonly string[] } ? T : readonly string[] diff --git a/packages/uniwind/src/core/web/cssListener.ts b/packages/uniwind/src/core/web/cssListener.ts index 4d99d823..68bde329 100644 --- a/packages/uniwind/src/core/web/cssListener.ts +++ b/packages/uniwind/src/core/web/cssListener.ts @@ -1,4 +1,4 @@ -import { StyleDependency } from '../../types' +import { StyleDependency } from '../../common/consts' import { UniwindListener } from '../listener' class CSSListenerBuilder { diff --git a/packages/uniwind/src/hoc/withUniwind.native.tsx b/packages/uniwind/src/hoc/withUniwind.native.tsx index 4fa6889e..139ad000 100644 --- a/packages/uniwind/src/hoc/withUniwind.native.tsx +++ b/packages/uniwind/src/hoc/withUniwind.native.tsx @@ -1,10 +1,10 @@ import { ComponentProps, useLayoutEffect, useReducer } from 'react' +import { StyleDependency } from '../common/consts' import { isDefined } from '../common/utils' import { useUniwindContext } from '../core/context' import { UniwindListener } from '../core/listener' import { Logger } from '../core/logger' import { UniwindStore } from '../core/native' -import { StyleDependency } from '../types' import { AnyObject, Component, OptionMapping, WithUniwind } from './types' import { classToColor, classToStyle, isClassProperty, isColorClassProperty, isStyleProperty } from './withUniwindUtils' diff --git a/packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts b/packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts index 1abe5019..70f70e79 100644 --- a/packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts +++ b/packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts @@ -1,10 +1,10 @@ import { useLayoutEffect, useRef, useState } from 'react' +import { StyleDependency } from '../../common/consts' import { arrayEquals } from '../../common/utils' import { useUniwindContext } from '../../core/context' import { UniwindListener } from '../../core/listener' import { Logger } from '../../core/logger' import { UniwindContextType } from '../../core/types' -import { StyleDependency } from '../../types' import { getVariableValue } from './getVariableValue' let warned = false diff --git a/packages/uniwind/src/hooks/useUniwind.ts b/packages/uniwind/src/hooks/useUniwind.ts index 54a56645..d5fa218b 100644 --- a/packages/uniwind/src/hooks/useUniwind.ts +++ b/packages/uniwind/src/hooks/useUniwind.ts @@ -1,9 +1,9 @@ import { useLayoutEffect, useState } from 'react' +import { StyleDependency } from '../common/consts' import { Uniwind } from '../core' import { useUniwindContext } from '../core/context' import { UniwindListener } from '../core/listener' import { ThemeName } from '../core/types' -import { StyleDependency } from '../types' export const useUniwind = (): { theme: ThemeName; hasAdaptiveThemes: boolean } => { const uniwindContext = useUniwindContext() diff --git a/packages/uniwind/src/index.ts b/packages/uniwind/src/index.ts index 2b42077d..f267c1a7 100644 --- a/packages/uniwind/src/index.ts +++ b/packages/uniwind/src/index.ts @@ -1,7 +1,6 @@ export * from './components/ScopedTheme' export { Uniwind } from './core' -export type { ThemeName } from './core/types' +export type { ThemeName, UniwindConfig } from './core/types' export { withUniwind } from './hoc' export type { ApplyUniwind, ApplyUniwindOptions } from './hoc/types' export { useCSSVariable, useResolveClassNames, useUniwind } from './hooks' -export type { UniwindConfig } from './types' diff --git a/packages/uniwind/src/metro/compileVirtual.ts b/packages/uniwind/src/metro/compileVirtual.ts deleted file mode 100644 index 5d6337ec..00000000 --- a/packages/uniwind/src/metro/compileVirtual.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { compile } from '@tailwindcss/node' -import { Scanner } from '@tailwindcss/oxide' -import { transform } from 'lightningcss' -import path from 'path' -import { Platform } from '../common/consts' -import { UniwindCSSVisitor } from '../css-visitor' -import { addMetaToStylesTemplate } from './addMetaToStylesTemplate' -import { Logger } from './logger' -import { ProcessorBuilder } from './processor' -import { Polyfills } from './types' -import { serializeJSObject } from './utils' - -type CompileVirtualConfig = { - cssPath: string - css: string - platform: Platform - themes: Array - polyfills: Polyfills | undefined - debug: boolean | undefined - candidates?: Array -} - -export const compileVirtual = async ({ css, cssPath, platform, themes, polyfills, debug, candidates }: CompileVirtualConfig) => { - const compiler = await compile(css, { - base: path.dirname(cssPath), - onDependency: () => void 0, - }) - const scanner = new Scanner({ - sources: [ - ...compiler.sources, - { - negated: false, - pattern: '**/*', - base: path.dirname(cssPath), - }, - ], - }) - const tailwindCSS = compiler.build(candidates ?? scanner.scan()) - - if (platform === Platform.Web) { - return transform({ - code: Buffer.from(tailwindCSS), - filename: 'uniwind.css', - visitor: new UniwindCSSVisitor(themes), - }).code.toString() - } - - const Processor = new ProcessorBuilder(themes, polyfills) - - Logger.debug = debug === true - Processor.transform(tailwindCSS) - - const stylesheet = serializeJSObject( - addMetaToStylesTemplate(Processor, platform), - (key, value) => `"${key}": ${value}`, - ) - const vars = serializeJSObject( - Processor.vars, - (key, value) => `get "${key}"() { return ${value} }`, - ) - const scopedVars = Object.fromEntries( - Object.entries(Processor.scopedVars) - .map(([scopedVarsName, scopedVars]) => [ - scopedVarsName, - serializeJSObject(scopedVars, (key, value) => `get "${key}"() { return ${value} }`), - ]), - ) - const serializedScopedVars = Object.entries(scopedVars) - .map(([scopedVarsName, scopedVars]) => `"${scopedVarsName}": ({ ${scopedVars} }),`) - .join('') - const currentColorVar = `get currentColor() { return rt.colorScheme === 'dark' ? '#ffffff' : '#000000' },` - - return [ - '({', - `scopedVars: ({ ${serializedScopedVars} }),`, - `vars: ({ ${currentColorVar} ${vars} }),`, - `stylesheet: ({ ${stylesheet} }),`, - '})', - ].join('') -} diff --git a/packages/uniwind/src/metro/index.ts b/packages/uniwind/src/metro/index.ts deleted file mode 100644 index d67a540b..00000000 --- a/packages/uniwind/src/metro/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './withUniwindConfig' diff --git a/packages/uniwind/src/metro/injectThemes.ts b/packages/uniwind/src/metro/injectThemes.ts deleted file mode 100644 index b09c6efe..00000000 --- a/packages/uniwind/src/metro/injectThemes.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { buildCSS } from '../css' -import { buildDtsFile } from '../utils/buildDtsFile' -import { stringifyThemes } from '../utils/stringifyThemes' - -type InjectThemesConfig = { - themes: Array - dtsPath?: string - input: string -} - -export const injectThemes = async ({ - themes, - dtsPath = 'uniwind-types.d.ts', - input, -}: InjectThemesConfig) => { - const stringifiedThemes = stringifyThemes(themes) - - buildDtsFile(dtsPath, stringifiedThemes) - await buildCSS(themes, input) - - // js generation - return stringifiedThemes -} diff --git a/packages/uniwind/src/metro/metro-transformer.ts b/packages/uniwind/src/metro/metro-transformer.ts deleted file mode 100644 index 1c19a158..00000000 --- a/packages/uniwind/src/metro/metro-transformer.ts +++ /dev/null @@ -1,116 +0,0 @@ -import fs from 'fs' -import type { JsTransformerConfig, JsTransformOptions } from 'metro-transform-worker' -import path from 'path' -import { name } from '../../package.json' -import { Platform } from '../common/consts' -import { compileVirtual } from './compileVirtual' -import { injectThemes } from './injectThemes' -import { UniwindConfig } from './types' - -let worker: typeof import('metro-transform-worker') - -try { - try { - const { unstable_transformerPath } = require('@expo/metro-config') as typeof import('@expo/metro-config') - - worker = require(unstable_transformerPath) - } catch { - worker = require('@expo/metro-config/build/transform-worker/transform-worker.js') - } -} catch { - worker = require('metro-transform-worker') -} - -export const transform = async ( - config: JsTransformerConfig & { - uniwind: UniwindConfig - }, - projectRoot: string, - filePath: string, - data: Buffer, - options: JsTransformOptions, -) => { - const isCss = options.type !== 'asset' && path.join(process.cwd(), config.uniwind.cssEntryFile) === path.join(projectRoot, filePath) - - if (filePath.endsWith('/components/web/metro-injected.js')) { - const cssPath = path.join(process.cwd(), config.uniwind.cssEntryFile) - const injectedThemesCode = await injectThemes({ - input: cssPath, - themes: config.uniwind.themes, - dtsPath: config.uniwind.dtsFile, - }) - - data = Buffer.from( - [ - `import { Uniwind } from '${name}';`, - `Uniwind.__reinit(() => ({}), ${injectedThemesCode});`, - ].join(''), - 'utf-8', - ) - } - - if (!isCss) { - return worker.transform(config, projectRoot, filePath, data, options) - } - - const getPlatform = () => { - if (!config.uniwind.isTV) { - return options.platform as Platform - } - - if (options.platform === Platform.Android) { - return Platform.AndroidTV - } - - if (options.platform === Platform.iOS) { - return Platform.AppleTV - } - - throw new Error(`Platform ${options.platform} not supported`) - } - - const cssPath = path.join(process.cwd(), config.uniwind.cssEntryFile) - const injectedThemesCode = await injectThemes({ - input: cssPath, - themes: config.uniwind.themes, - dtsPath: config.uniwind.dtsFile, - }) - const css = fs.readFileSync(cssPath, 'utf-8') - const platform = getPlatform() - const virtualCode = await compileVirtual({ - css, - platform, - themes: config.uniwind.themes, - polyfills: config.uniwind.polyfills, - cssPath, - debug: config.uniwind.debug, - }) - const isWeb = platform === Platform.Web - - data = Buffer.from( - isWeb - ? virtualCode - : [ - `const { Uniwind } = require('${name}');`, - `Uniwind.__reinit(rt => ${virtualCode}, ${injectedThemesCode});`, - ].join(''), - 'utf-8', - ) - - const transform: any = await worker.transform( - config, - projectRoot, - `${filePath}${isWeb ? '' : '.js'}`, - data, - options, - ) - - transform.output[0].data.css ??= {} - transform.output[0].data.css.skipCache = true - - if (!isWeb) { - transform.output[0].data.css.code = '' - } - - return transform -} diff --git a/packages/uniwind/src/metro/processor/index.ts b/packages/uniwind/src/metro/processor/index.ts deleted file mode 100644 index 10dedf91..00000000 --- a/packages/uniwind/src/metro/processor/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './processor' diff --git a/packages/uniwind/src/metro/utils/index.ts b/packages/uniwind/src/metro/utils/index.ts deleted file mode 100644 index 0dee13a6..00000000 --- a/packages/uniwind/src/metro/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './common' -export * from './serialize' diff --git a/packages/uniwind/src/types.ts b/packages/uniwind/src/types.ts deleted file mode 100644 index 799ccac4..00000000 --- a/packages/uniwind/src/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -export enum StyleDependency { - ColorScheme = 1, - Theme = 2, - Dimensions = 3, - Orientation = 4, - Insets = 5, - FontScale = 6, - Rtl = 7, - AdaptiveThemes = 8, - Variables = 9, -} - -export const enum Orientation { - Portrait = 'portrait', - Landscape = 'landscape', -} - -export const enum ColorScheme { - Light = 'light', - Dark = 'dark', -} - -export interface UniwindConfig {} diff --git a/packages/uniwind/src/utils/stringifyThemes.ts b/packages/uniwind/src/utils/stringifyThemes.ts deleted file mode 100644 index f95657f3..00000000 --- a/packages/uniwind/src/utils/stringifyThemes.ts +++ /dev/null @@ -1 +0,0 @@ -export const stringifyThemes = (themes: Array = []) => `[${themes.map((theme) => `'${theme}'`).join(', ')}]` diff --git a/packages/uniwind/tests/e2e/global-setup.ts b/packages/uniwind/tests/e2e/global-setup.ts index d06de9da..72f30330 100644 --- a/packages/uniwind/tests/e2e/global-setup.ts +++ b/packages/uniwind/tests/e2e/global-setup.ts @@ -1,8 +1,9 @@ import { build } from 'esbuild' -import { mkdirSync, readFileSync, writeFileSync } from 'fs' +import { mkdirSync, writeFileSync } from 'fs' import { resolve } from 'path' +import { UniwindBundlerConfig } from '../../src/bundler/config' +import { compileCSS } from '../../src/bundler/css-compiler' import { Platform } from '../../src/common/consts' -import { compileVirtual } from '../../src/metro/compileVirtual' // Playwright runs globalSetup with cwd = directory containing playwright.config.ts // which is packages/uniwind/ @@ -16,17 +17,10 @@ export default async function globalSetup() { mkdirSync(GENERATED_DIR, { recursive: true }) // 1. Compile test.css โ†’ real Tailwind CSS for web - const cssPath = resolve(ROOT, 'tests/test.css') - const css = readFileSync(cssPath, 'utf-8') - - const compiledCSS = await compileVirtual({ - css, - cssPath, - debug: false, - platform: Platform.Web, - themes: ['light', 'dark'], - polyfills: undefined, - }) + const bundlerConfig = UniwindBundlerConfig.fromMetroConfig({ + cssEntryFile: 'tests/test.css', + }, Platform.Web) + const compiledCSS = await compileCSS(bundlerConfig) writeFileSync(CSS_PATH, compiledCSS, 'utf-8') console.log(`[e2e setup] Compiled CSS written to ${CSS_PATH}`) diff --git a/packages/uniwind/tests/setup.native.ts b/packages/uniwind/tests/setup.native.ts index 002bb3a8..26dbf479 100644 --- a/packages/uniwind/tests/setup.native.ts +++ b/packages/uniwind/tests/setup.native.ts @@ -1,23 +1,16 @@ -import { readFileSync } from 'fs' -import { resolve } from 'path' import { Dimensions } from 'react-native' +import { UniwindBundlerConfig } from '../src/bundler/config' +import { compileCSS } from '../src/bundler/css-compiler' import { Platform } from '../src/common/consts' -import { compileVirtual } from '../src/metro/compileVirtual' import { SAFE_AREA_INSET_BOTTOM, SAFE_AREA_INSET_TOP, SCREEN_HEIGHT, SCREEN_WIDTH } from './consts' jest.spyOn(Dimensions, 'get').mockReturnValue({ width: SCREEN_WIDTH, height: SCREEN_HEIGHT, scale: 1, fontScale: 1 }) beforeAll(async () => { - const cssPath = resolve('./tests/test.css') - const css = readFileSync(cssPath, 'utf-8') - const virtualCode = await compileVirtual({ - css, - cssPath, - debug: true, - platform: Platform.iOS, - themes: ['light', 'dark'], - polyfills: undefined, - }) + const bundlerConfig = UniwindBundlerConfig.fromMetroConfig({ + cssEntryFile: './tests/test.css', + }, Platform.iOS) + const virtualCode = await compileCSS(bundlerConfig) eval( `const { Uniwind } = require('../src/core/config/config.native'); diff --git a/packages/uniwind/tsconfig.json b/packages/uniwind/tsconfig.json index b33863b0..72dfe706 100644 --- a/packages/uniwind/tsconfig.json +++ b/packages/uniwind/tsconfig.json @@ -9,14 +9,13 @@ "isolatedModules": true, "strict": true, "noUncheckedIndexedAccess": true, + "rootDir": "src", "paths": { - "@/css": ["./src/css/index.ts"], - "@/css/*": ["./src/css/*"], - "@/css-visitor": ["./src/css-visitor/index.ts"], - "@/css-visitor/*": ["./src/css-visitor/*"], "@/metro": ["./src/metro/index.ts"], "@/metro/*": ["./src/metro/*"], - "@/utils/*": ["./src/utils/*"] + "@/utils/*": ["./src/utils/*"], + "@/common/*": ["./src/common/*"], + "@/bundler/*": ["./src/bundler/*"] }, "moduleResolution": "Bundler", "module": "ESNext", From d7e458f89df84c7f8fea646c261131ffe88d3791 Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Thu, 7 May 2026 14:21:37 +0200 Subject: [PATCH 03/13] chore: remove unused --- packages/uniwind/src/bundler/css-processor/css-processor.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/uniwind/src/bundler/css-processor/css-processor.ts diff --git a/packages/uniwind/src/bundler/css-processor/css-processor.ts b/packages/uniwind/src/bundler/css-processor/css-processor.ts deleted file mode 100644 index e69de29b..00000000 From 65cf0db7754d5e0152cdaf78483344539bfbeb41 Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Thu, 7 May 2026 14:36:28 +0200 Subject: [PATCH 04/13] docs: context.md --- context.md | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 context.md diff --git a/context.md b/context.md new file mode 100644 index 00000000..df874c84 --- /dev/null +++ b/context.md @@ -0,0 +1,200 @@ +# Uniwind Context + +This document captures working context for `packages/uniwind`, the published `uniwind` package in this monorepo. Keep it current when architecture, public APIs, supported platforms, or build/runtime contracts change. + +## Product + +Uniwind is Tailwind CSS bindings for React Native and React Native Web. It lets users write `className` props on React Native components while doing as much style work as possible at build time. + +Primary promise: fast Tailwind styling for React Native with web parity where practical. + +Positioning: Uniwind optimizes for build-time Tailwind-to-React-Native artifacts, minimal runtime work, and React Native Web parity. It is not primarily a full design-system/runtime styling framework, a NativeWind compatibility layer, or a web-first CSS bridge. + +Core user-facing features: + +- Out-of-the-box `className` bindings for React Native components. +- Tailwind v4 CSS compilation into native runtime style artifacts or web CSS. +- Light, dark, and extra named themes. +- `active`, `focus`, `disabled`, RTL, orientation, responsive, data attribute, and platform-aware variants. +- CSS custom property reads and updates from React Native code. +- Scoped themes through `ScopedTheme`. +- Metro and Vite integration. + +Supported platforms: iOS, Android, web, Android TV, and Apple TV. Other React Native targets are out of scope until tests and docs explicitly cover them. + +## Package Boundaries + +Important paths: + +- `packages/uniwind/src/index.ts`: public package entrypoint. +- `packages/uniwind/src/components`: React Native component wrappers and web exports. +- `packages/uniwind/src/core`: runtime config, listeners, native style store, and web style extraction. +- `packages/uniwind/src/hooks`: public hooks. +- `packages/uniwind/src/hoc`: `withUniwind` for custom components. +- `packages/uniwind/src/bundler`: Metro/Vite adapters, Tailwind compilation, CSS processing, artifact generation. +- `packages/uniwind/tests`: native, web, type, and e2e tests. +- `packages/uniwind/uniwind.css`: package-level CSS artifact referenced by package `style` export. + +Public exports from `src/index.ts`: + +- `Uniwind` runtime/config object. +- `ScopedTheme` component. +- `withUniwind` HOC and related types. +- `useCSSVariable`, `useResolveClassNames`, `useUniwind` hooks. +- `ThemeName` and `UniwindConfig` types. + +Package subpath exports: + +- `uniwind`: main runtime API. +- `uniwind/components`: React Native component replacements. +- `uniwind/components/*`: individual component replacements. +- `uniwind/metro`: Metro adapter. +- `uniwind/vite`: Vite plugin. +- `uniwind/types`: generated/user-facing type support. + +Stability policy: public package and subpath exports are semver-stable. Generated artifact internals are implementation details unless explicitly documented, with two notable user-facing surfaces: generated theme typings and the package `style` export (`uniwind.css`). + +Dependency policy: peer dependency floors are support contracts. Raising support floors for Tailwind, React, or React Native requires semver-major unless an upstream ecosystem break makes that impossible to honor. + +## Runtime Model + +Native runtime: + +- Build output injects a generated stylesheet callback into `Uniwind.__reinit(...)`. +- `UniwindStore` holds generated style records, theme variables, scoped variables, runtime state, and per-theme caches. +- `UniwindStore.getStyles(className, props, state, context)` resolves classes into React Native style objects. +- Cache keys include class names, component state, and whether theme is scoped. +- Resolved styles subscribe to only dependencies they use, then invalidate cache entries on change. +- Runtime dependencies are represented by `StyleDependency`: theme, dimensions, orientation, insets, font scale, RTL, adaptive themes, and variables. +- Native style resolution filters rules by screen width, orientation, theme, RTL, active/focus/disabled state, and `data-*` props. +- Native post-processing adapts CSS concepts to RN shapes, including line-height multipliers, shadows, transforms, gradients, visibility, borders, outlines, and font variants. + +Web runtime: + +- Web keeps styles in CSS and passes `{ $$css: true, tailwind: className }` through RNW style arrays. +- `getWebStyles` uses a hidden DOM element to compute style values when a JS value is needed, such as color extraction or `useResolveClassNames`. +- `CSSListener` tracks active CSS rules and media queries, then notifies subscribers when class-dependent media rules change. +- `ScopedTheme` renders a `div` with the theme class and `display: contents` on web. +- Dynamic CSS variable updates are written into a generated `#uniwind-dynamic-styles` style element. + +Shared runtime: + +- `Uniwind.setTheme(theme | 'system')` switches explicit themes or returns to system adaptive light/dark. +- `Uniwind.currentTheme` and `Uniwind.hasAdaptiveThemes` back `useUniwind`. +- `Uniwind.updateCSSVariables(theme, variables)` updates theme variables and notifies variable subscribers. +- `Uniwind.updateInsets(insets)` is native-only behavior and updates safe-area-style runtime values. +- `ScopedTheme` sets `UniwindContext.scopedTheme`; scoped subtree ignores global theme changes for style resolution. + +## Build And Bundler Model + +Configuration shape: + +- `cssEntryFile`: required CSS entry path, resolved from `process.cwd()`. +- `extraThemes`: optional named themes added to default `light` and `dark`. +- `dtsFile`: optional generated declaration file path, default `uniwind-types.d.ts`. +- Metro-only `polyfills.rem`: custom rem base, default `16`. +- Metro-only `debug` and `isTV` flags exist in types. + +Compilation flow: + +- `compileTailwind` reads `cssEntryFile`, runs Tailwind v4 compile, scans files under the CSS entry directory, and builds final CSS. +- `compileCSS` routes to web or native by platform. +- `compileWebCSS` runs Lightning CSS with `UniwindCSSVisitor` and returns CSS. +- `compileNativeCSS` runs `ProcessorBuilder`, serializes variables, scoped variables, and native stylesheet metadata into JS source. +- `UniwindBundlerConfig.generateArtifacts` writes CSS artifacts and generated theme typings. + +Metro integration: + +- `withUniwindConfig(config, uniwindConfig)` patches Metro graph support for uncached modules. +- Metro adds `css` as source extension and removes it from asset extensions. +- Metro transformer handles the configured CSS entry file specially. +- Native platform CSS transforms into a JS module that calls `Uniwind.__reinit(...)`. +- Web platform CSS transforms into CSS plus web runtime setup. +- Resolver swaps React Native component imports to Uniwind-aware implementations where needed. + +Vite integration: + +- `uniwind(config)` returns a pre Vite plugin. +- Vite aliases `react-native` to Uniwind web components, except imports from Uniwind internals resolve back to `react-native-web`. +- Vite replaces RNW `createOrderedCSSStyleSheet` with Uniwind's ordered stylesheet implementation. +- Vite uses Lightning CSS with `UniwindCSSVisitor`. +- Vite generates artifacts on `buildStart` and `generateBundle`. + +## CSS Processing + +Native processing converts Tailwind-generated CSS into metadata-rich style records. + +Important concepts: + +- A `Style` record stores entries, breakpoint bounds, orientation, theme, RTL, native flag, dependencies, source index, class name, important properties, selector complexity, pseudo states, and data attributes. +- CSS variables live in `vars`; theme and platform scoped variables live in `scopedVars` with internal prefixes. +- The processor treats declarations under `:root` or outside class rules as variables. +- Theme variants are recognized from known theme names. +- Data attribute variants support boolean `data-x` and exact `data-x="value"` matching against component props. +- Media queries drive dimensions, orientation, color scheme, platform, and native/web-specific metadata. +- Important declarations are preserved as `importantProperties`. +- Unsupported CSS features may be silently ignored on native. Prefer documenting support coverage over adding noisy runtime failures for every unsupported CSS construct. + +Web visitor behavior: + +- Theme root rules in Tailwind theme layer become theme class rules. +- Theme-prefixed class rules are scoped with CSS `@scope` to selected theme classes and excluded from other themes. +- Visitor state is cleaned between transforms. + +## Components And HOC + +Native components: + +- Native wrappers import the underlying `react-native` component. +- `useStyle(className, props, state)` resolves `className` through `UniwindStore` and subscribes to style dependencies. +- Most components combine generated style before user style: `[generatedStyle, props.style]`, preserving user overrides. +- Stateful components such as `Pressable` pass `pressed`, `focused`, and `disabled` state into style resolution. +- Accent-capable components use `accentColor` extraction helpers where needed. + +Web components: + +- Web wrappers import from `react-native` as resolved by bundler aliases. +- Web wrappers map `className` to RNW CSS style markers through `toRNWClassName`. +- Web wrappers pass generated `dataSet` so data attribute variants can match. + +`withUniwind`: + +- Auto mode maps `className`-style props to matching RN style props and color class props to color props. +- Manual mode maps custom class props to custom target props and can extract a single style property. +- Native mode resolves to concrete RN style objects. +- Web mode usually emits RNW CSS style markers and uses computed style only for extracted values. + +## Testing And Quality Gates + +Package scripts: + +- `bun run build`: unbuild package outputs. +- `bun run check:typescript`: TypeScript no-emit check. +- `bun run lint`: oxlint on `src`. +- `bun run circular:check`: dpdm circular dependency check. +- `bun run test:native`: Jest native tests. +- `bun run test:web`: Jest web tests. +- `bun run test:types`: type-level tests. +- `bun run test:e2e`: Playwright e2e tests. + +Root scripts use Turbo for monorepo-wide build, typecheck, lint, test, format, and circular checks. + +Testing layout: + +- `tests/native`: component behavior and native style parsing. +- `tests/web`: web config, components, and HOC behavior. +- `tests/type-test`: public type expectations. +- `tests/e2e`: browser checks for web style extraction and generated artifacts. + +Source-of-truth policy: repository code and tests win for implementation details. External docs at `docs.uniwind.dev` describe intended public behavior and should be updated when public behavior changes. + +## Engineering Constraints + +- Runtime performance matters. Prefer build-time CSS processing and narrow runtime invalidation over broad recomputation. +- Preserve user style precedence when adding component wrappers. +- Keep native and web behavior aligned unless platform constraints require divergence. +- Any new runtime dependency should map to `StyleDependency` and invalidate only affected subscribers. +- Theme-aware changes must account for global theme, adaptive system theme, and `ScopedTheme`. +- CSS variables must keep lazy getter semantics on native because values may depend on current runtime state. +- Avoid introducing compatibility paths without known consumers or persisted behavior. +- Add tests for native, web, and types when changing public API or cross-platform behavior. From 3efbbb56659d01b1ad9fe47492630b107f20139a Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Thu, 7 May 2026 14:38:05 +0200 Subject: [PATCH 05/13] chore: unused aliases --- packages/uniwind/build.config.ts | 2 -- packages/uniwind/tsconfig.json | 3 --- 2 files changed, 5 deletions(-) diff --git a/packages/uniwind/build.config.ts b/packages/uniwind/build.config.ts index 9c0dc7a2..ff945993 100644 --- a/packages/uniwind/build.config.ts +++ b/packages/uniwind/build.config.ts @@ -95,8 +95,6 @@ export default defineBuildConfig({ }), ], alias: { - '@/metro': srcPath('metro'), - '@/utils': srcPath('utils'), '@/common': srcPath('common'), '@/bundler': srcPath('bundler'), }, diff --git a/packages/uniwind/tsconfig.json b/packages/uniwind/tsconfig.json index 72dfe706..0da8ebba 100644 --- a/packages/uniwind/tsconfig.json +++ b/packages/uniwind/tsconfig.json @@ -11,9 +11,6 @@ "noUncheckedIndexedAccess": true, "rootDir": "src", "paths": { - "@/metro": ["./src/metro/index.ts"], - "@/metro/*": ["./src/metro/*"], - "@/utils/*": ["./src/utils/*"], "@/common/*": ["./src/common/*"], "@/bundler/*": ["./src/bundler/*"] }, From 5c733ecc4ca3a7d14f38442a0da758eca52218c1 Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Thu, 7 May 2026 14:44:45 +0200 Subject: [PATCH 06/13] chore: add new line before reinit in vite adapter --- packages/uniwind/src/bundler/adapters/vite/vite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/uniwind/src/bundler/adapters/vite/vite.ts b/packages/uniwind/src/bundler/adapters/vite/vite.ts index cd0de2ec..cc256bf1 100644 --- a/packages/uniwind/src/bundler/adapters/vite/vite.ts +++ b/packages/uniwind/src/bundler/adapters/vite/vite.ts @@ -80,7 +80,7 @@ export const uniwind = (config: UniwindConfig): Plugin => { if (normalizedId.includes('uniwind/dist') && normalizedId.includes('config/config.js')) { return { - code: `${code}Uniwind.__reinit(() => ({}), ${bundlerConfig.stringifiedThemes})`, + code: `${code}\n;Uniwind.__reinit(() => ({}), ${bundlerConfig.stringifiedThemes})`, } } }, From 8e5b6403e0964dc80872e6ad1ed46dba8a9ca22a Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Thu, 7 May 2026 14:49:16 +0200 Subject: [PATCH 07/13] chore: fs promise to read file for tailwind compilation --- packages/uniwind/src/bundler/css-compiler/compileTailwind.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts b/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts index 0cd27413..dab363f9 100644 --- a/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts +++ b/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts @@ -5,7 +5,7 @@ import path from 'path' import { UniwindBundlerConfig } from '../config' export const compileTailwind = async (bundlerConfig: UniwindBundlerConfig) => { - const css = fs.readFileSync(bundlerConfig.cssPath, 'utf-8') + const css = await fs.promises.readFile(bundlerConfig.cssPath, 'utf-8') const compiler = await compile(css, { base: path.dirname(bundlerConfig.cssPath), onDependency: () => void 0, From 52ba715dbb38ea7a80d283a25c3fdaf42b17ab5c Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Thu, 7 May 2026 14:53:31 +0200 Subject: [PATCH 08/13] chore: consistent type imports --- packages/uniwind/.oxlintrc.json | 3 ++- packages/uniwind/src/bundler/adapters/metro/patches.ts | 3 ++- packages/uniwind/src/bundler/adapters/metro/resolvers.ts | 2 +- .../uniwind/src/bundler/adapters/metro/transformer.ts | 8 +++++--- .../uniwind/src/bundler/artifacts/css/extraUtilities.ts | 2 +- packages/uniwind/src/bundler/css-compiler/compileCSS.ts | 2 +- .../uniwind/src/bundler/css-compiler/compileNativeCSS.ts | 2 +- .../uniwind/src/bundler/css-compiler/compileTailwind.ts | 2 +- .../uniwind/src/bundler/css-compiler/compileWebCSS.ts | 2 +- .../src/bundler/css-processor/addMetaToStylesTemplate.ts | 4 ++-- packages/uniwind/src/bundler/css-processor/color.ts | 5 +++-- packages/uniwind/src/bundler/css-processor/css.ts | 4 ++-- packages/uniwind/src/bundler/css-processor/functions.ts | 2 +- packages/uniwind/src/bundler/css-processor/mq.ts | 7 ++++--- packages/uniwind/src/bundler/css-processor/processor.ts | 7 ++++--- packages/uniwind/src/bundler/css-processor/types.ts | 2 +- packages/uniwind/src/bundler/css-processor/units.ts | 2 +- packages/uniwind/src/bundler/css-processor/var.ts | 2 +- .../uniwind/src/bundler/css-visitor/function-visitor.ts | 2 +- packages/uniwind/src/bundler/css-visitor/rule-visitor.ts | 2 +- packages/uniwind/src/bundler/css-visitor/visitor.ts | 2 +- .../src/components/ScopedTheme/ScopedTheme.native.tsx | 2 +- .../uniwind/src/components/native/ActivityIndicator.tsx | 3 ++- packages/uniwind/src/components/native/Button.tsx | 3 ++- packages/uniwind/src/components/native/FlatList.tsx | 3 ++- packages/uniwind/src/components/native/Image.tsx | 3 ++- .../uniwind/src/components/native/ImageBackground.tsx | 3 ++- .../uniwind/src/components/native/InputAccessoryView.tsx | 5 +++-- .../src/components/native/KeyboardAvoidingView.tsx | 3 ++- packages/uniwind/src/components/native/Modal.tsx | 3 ++- packages/uniwind/src/components/native/Pressable.tsx | 3 ++- packages/uniwind/src/components/native/RefreshControl.tsx | 3 ++- packages/uniwind/src/components/native/SafeAreaView.tsx | 3 ++- packages/uniwind/src/components/native/ScrollView.tsx | 3 ++- packages/uniwind/src/components/native/SectionList.tsx | 3 ++- packages/uniwind/src/components/native/Switch.tsx | 5 +++-- packages/uniwind/src/components/native/Text.tsx | 5 +++-- packages/uniwind/src/components/native/TextInput.tsx | 5 +++-- .../uniwind/src/components/native/TouchableHighlight.tsx | 5 +++-- .../src/components/native/TouchableNativeFeedback.tsx | 5 +++-- .../uniwind/src/components/native/TouchableOpacity.tsx | 5 +++-- .../src/components/native/TouchableWithoutFeedback.tsx | 5 +++-- packages/uniwind/src/components/native/View.tsx | 3 ++- .../uniwind/src/components/native/VirtualizedList.tsx | 3 ++- packages/uniwind/src/components/native/useAccentColor.ts | 2 +- packages/uniwind/src/components/native/useStyle.ts | 2 +- packages/uniwind/src/components/web/ActivityIndicator.tsx | 3 ++- packages/uniwind/src/components/web/Button.tsx | 3 ++- packages/uniwind/src/components/web/FlatList.tsx | 3 ++- packages/uniwind/src/components/web/Image.tsx | 3 ++- packages/uniwind/src/components/web/ImageBackground.tsx | 3 ++- .../uniwind/src/components/web/KeyboardAvoidingView.tsx | 3 ++- packages/uniwind/src/components/web/Modal.tsx | 3 ++- packages/uniwind/src/components/web/Pressable.tsx | 3 ++- packages/uniwind/src/components/web/RefreshControl.tsx | 3 ++- packages/uniwind/src/components/web/SafeAreaView.tsx | 3 ++- packages/uniwind/src/components/web/ScrollView.tsx | 3 ++- packages/uniwind/src/components/web/SectionList.tsx | 3 ++- packages/uniwind/src/components/web/Switch.tsx | 3 ++- packages/uniwind/src/components/web/Text.tsx | 3 ++- packages/uniwind/src/components/web/TextInput.tsx | 3 ++- .../uniwind/src/components/web/TouchableHighlight.tsx | 3 ++- packages/uniwind/src/components/web/TouchableOpacity.tsx | 3 ++- .../src/components/web/TouchableWithoutFeedback.tsx | 3 ++- packages/uniwind/src/components/web/View.tsx | 3 ++- packages/uniwind/src/components/web/VirtualizedList.tsx | 3 ++- packages/uniwind/src/core/config/config.common.ts | 8 +++++--- packages/uniwind/src/core/config/config.native.ts | 4 ++-- packages/uniwind/src/core/config/config.ts | 2 +- packages/uniwind/src/core/native/store.ts | 2 +- packages/uniwind/src/core/types.ts | 2 +- packages/uniwind/src/core/web/getWebStyles.ts | 2 +- packages/uniwind/src/hoc/types.ts | 4 ++-- packages/uniwind/src/hoc/withUniwind.native.tsx | 7 ++++--- packages/uniwind/src/hoc/withUniwind.tsx | 5 +++-- .../src/hooks/useCSSVariable/getVariableValue.native.ts | 2 +- .../uniwind/src/hooks/useCSSVariable/useCSSVariable.ts | 2 +- packages/uniwind/src/hooks/useResolveClassNames.ts | 2 +- packages/uniwind/src/hooks/useUniwind.ts | 2 +- 79 files changed, 156 insertions(+), 103 deletions(-) diff --git a/packages/uniwind/.oxlintrc.json b/packages/uniwind/.oxlintrc.json index 341c8920..ac96311e 100644 --- a/packages/uniwind/.oxlintrc.json +++ b/packages/uniwind/.oxlintrc.json @@ -5,7 +5,8 @@ "rules": { "unicorn/no-empty-file": "off", "typescript/strict-boolean-expressions": "off", - "typescript/no-implied-eval": "off" + "typescript/no-implied-eval": "off", + "typescript/consistent-type-imports": "error" }, "ignorePatterns": [ "build.config.ts", diff --git a/packages/uniwind/src/bundler/adapters/metro/patches.ts b/packages/uniwind/src/bundler/adapters/metro/patches.ts index b3aad3aa..84d90126 100644 --- a/packages/uniwind/src/bundler/adapters/metro/patches.ts +++ b/packages/uniwind/src/bundler/adapters/metro/patches.ts @@ -1,5 +1,6 @@ import type { Graph, Result as GraphResult } from '@expo/metro/metro/DeltaBundler/Graph' import FileStoreBase from 'metro-cache/private/stores/FileStore' +import type * as MetroGraphModule from 'metro/private/DeltaBundler/Graph' import type { Options as GraphOptions } from 'metro/private/DeltaBundler/types' import os from 'os' import path from 'path' @@ -24,7 +25,7 @@ interface TraverseDependencies { } export const patchMetroGraphToSupportUncachedModules = () => { - const { Graph } = require('metro/private/DeltaBundler/Graph') as typeof import('metro/private/DeltaBundler/Graph') + const { Graph } = require('metro/private/DeltaBundler/Graph') as typeof MetroGraphModule // oxlint-disable-next-line @typescript-eslint/unbound-method const original_traverseDependencies = Graph.prototype.traverseDependencies as unknown as TraverseDependencies diff --git a/packages/uniwind/src/bundler/adapters/metro/resolvers.ts b/packages/uniwind/src/bundler/adapters/metro/resolvers.ts index bca30259..1b18d044 100644 --- a/packages/uniwind/src/bundler/adapters/metro/resolvers.ts +++ b/packages/uniwind/src/bundler/adapters/metro/resolvers.ts @@ -1,4 +1,4 @@ -import { CustomResolutionContext, CustomResolver } from 'metro-resolver' +import type { CustomResolutionContext, CustomResolver } from 'metro-resolver' import { basename, dirname, sep } from 'node:path' type ResolverConfig = { diff --git a/packages/uniwind/src/bundler/adapters/metro/transformer.ts b/packages/uniwind/src/bundler/adapters/metro/transformer.ts index 21d78921..d0234435 100644 --- a/packages/uniwind/src/bundler/adapters/metro/transformer.ts +++ b/packages/uniwind/src/bundler/adapters/metro/transformer.ts @@ -1,17 +1,19 @@ import { UniwindBundlerConfig } from '@/bundler/config' import { compileCSS } from '@/bundler/css-compiler' -import { UniwindMetroConfig } from '@/bundler/types' +import type { UniwindMetroConfig } from '@/bundler/types' import { Platform } from '@/common/consts' +import type * as ExpoMetroConfig from '@expo/metro-config' +import type * as MetroTransformWorker from 'metro-transform-worker' import type { JsTransformerConfig, JsTransformOptions } from 'metro-transform-worker' import path from 'path' const cssArtifactPath = path.resolve(__dirname, '../../uniwind.css') -let worker: typeof import('metro-transform-worker') +let worker: typeof MetroTransformWorker try { try { - const { unstable_transformerPath } = require('@expo/metro-config') as typeof import('@expo/metro-config') + const { unstable_transformerPath } = require('@expo/metro-config') as typeof ExpoMetroConfig worker = require(unstable_transformerPath) } catch { diff --git a/packages/uniwind/src/bundler/artifacts/css/extraUtilities.ts b/packages/uniwind/src/bundler/artifacts/css/extraUtilities.ts index f705d710..77fdc0f3 100644 --- a/packages/uniwind/src/bundler/artifacts/css/extraUtilities.ts +++ b/packages/uniwind/src/bundler/artifacts/css/extraUtilities.ts @@ -1,4 +1,4 @@ -import { RNStyle } from '../../../core/types' +import type { RNStyle } from '../../../core/types' const toKebabCase = (str: string) => str.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`) diff --git a/packages/uniwind/src/bundler/css-compiler/compileCSS.ts b/packages/uniwind/src/bundler/css-compiler/compileCSS.ts index 8d51a4f3..bc3e7566 100644 --- a/packages/uniwind/src/bundler/css-compiler/compileCSS.ts +++ b/packages/uniwind/src/bundler/css-compiler/compileCSS.ts @@ -1,5 +1,5 @@ import { Platform } from '@/common/consts' -import { UniwindBundlerConfig } from '../config' +import type { UniwindBundlerConfig } from '../config' import { compileNativeCSS } from './compileNativeCSS' import { compileTailwind } from './compileTailwind' import { compileWebCSS } from './compileWebCSS' diff --git a/packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts b/packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts index 1fc2acc9..79d4937b 100644 --- a/packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts +++ b/packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts @@ -1,4 +1,4 @@ -import { UniwindBundlerConfig } from '../config' +import type { UniwindBundlerConfig } from '../config' import { addMetaToStylesTemplate, ProcessorBuilder, serializeJSObject } from '../css-processor' export const compileNativeCSS = (bundlerConfig: UniwindBundlerConfig, tailwindCSS: string) => { diff --git a/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts b/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts index dab363f9..402c2ea3 100644 --- a/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts +++ b/packages/uniwind/src/bundler/css-compiler/compileTailwind.ts @@ -2,7 +2,7 @@ import { compile } from '@tailwindcss/node' import { Scanner } from '@tailwindcss/oxide' import fs from 'fs' import path from 'path' -import { UniwindBundlerConfig } from '../config' +import type { UniwindBundlerConfig } from '../config' export const compileTailwind = async (bundlerConfig: UniwindBundlerConfig) => { const css = await fs.promises.readFile(bundlerConfig.cssPath, 'utf-8') diff --git a/packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts b/packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts index b7d791a2..51ebcfde 100644 --- a/packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts +++ b/packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts @@ -1,5 +1,5 @@ import { transform } from 'lightningcss' -import { UniwindBundlerConfig } from '../config' +import type { UniwindBundlerConfig } from '../config' import { UniwindCSSVisitor } from '../css-visitor' export const compileWebCSS = (bundlerConfig: UniwindBundlerConfig, tailwindCSS: string) => { diff --git a/packages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.ts b/packages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.ts index d7662c58..7bca0af3 100644 --- a/packages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.ts +++ b/packages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.ts @@ -1,8 +1,8 @@ import { Platform, StyleDependency } from '@/common/consts' import { isDefined } from '@/common/utils' -import { ProcessorBuilder } from './processor' +import type { ProcessorBuilder } from './processor' import { serialize } from './serialize' -import { StyleSheetTemplate } from './types' +import type { StyleSheetTemplate } from './types' import { toCamelCase } from './utils' const extractVarsFromString = (value: string) => { diff --git a/packages/uniwind/src/bundler/css-processor/color.ts b/packages/uniwind/src/bundler/css-processor/color.ts index 7033d1af..88d030b0 100644 --- a/packages/uniwind/src/bundler/css-processor/color.ts +++ b/packages/uniwind/src/bundler/css-processor/color.ts @@ -1,5 +1,6 @@ -import { Color as ColorType, converter, formatHex, formatHex8, parse } from 'culori' -import { CssColor, UnresolvedColor } from 'lightningcss' +import type { Color as ColorType } from 'culori' +import { converter, formatHex, formatHex8, parse } from 'culori' +import type { CssColor, UnresolvedColor } from 'lightningcss' import { Logger } from '../logger' import type { ProcessorBuilder } from './processor' import { pipe } from './utils' diff --git a/packages/uniwind/src/bundler/css-processor/css.ts b/packages/uniwind/src/bundler/css-processor/css.ts index fbff192c..2e6492f8 100644 --- a/packages/uniwind/src/bundler/css-processor/css.ts +++ b/packages/uniwind/src/bundler/css-processor/css.ts @@ -1,8 +1,8 @@ -import { OverflowKeyword } from 'lightningcss' +import type { OverflowKeyword } from 'lightningcss' import { isDefined } from '../../common/utils' import { Logger } from '../logger' import type { ProcessorBuilder } from './processor' -import { DeclarationValues } from './types' +import type { DeclarationValues } from './types' import { deepEqual, pipe, roundToPrecision, shouldBeSerialized } from './utils' export class CSS { diff --git a/packages/uniwind/src/bundler/css-processor/functions.ts b/packages/uniwind/src/bundler/css-processor/functions.ts index c895dc6b..7d791647 100644 --- a/packages/uniwind/src/bundler/css-processor/functions.ts +++ b/packages/uniwind/src/bundler/css-processor/functions.ts @@ -1,4 +1,4 @@ -import { CalcFor_DimensionPercentageFor_LengthValue, CalcFor_Length, CssColor, Function as FunctionType } from 'lightningcss' +import type { CalcFor_DimensionPercentageFor_LengthValue, CalcFor_Length, CssColor, Function as FunctionType } from 'lightningcss' import { Logger } from '../logger' import type { ProcessorBuilder } from './processor' import { pipe } from './utils' diff --git a/packages/uniwind/src/bundler/css-processor/mq.ts b/packages/uniwind/src/bundler/css-processor/mq.ts index c06dc94e..02be572b 100644 --- a/packages/uniwind/src/bundler/css-processor/mq.ts +++ b/packages/uniwind/src/bundler/css-processor/mq.ts @@ -1,7 +1,8 @@ -import { ColorScheme, Orientation, Platform } from '@/common/consts' -import { MediaQuery, QueryFeatureFor_MediaFeatureId } from 'lightningcss' +import type { ColorScheme, Orientation } from '@/common/consts' +import { Platform } from '@/common/consts' +import type { MediaQuery, QueryFeatureFor_MediaFeatureId } from 'lightningcss' import type { ProcessorBuilder } from './processor' -import { MediaQueryResolver } from './types' +import type { MediaQueryResolver } from './types' export class MQ { constructor(private readonly Processor: ProcessorBuilder) {} diff --git a/packages/uniwind/src/bundler/css-processor/processor.ts b/packages/uniwind/src/bundler/css-processor/processor.ts index c5850780..e638e2f0 100644 --- a/packages/uniwind/src/bundler/css-processor/processor.ts +++ b/packages/uniwind/src/bundler/css-processor/processor.ts @@ -1,12 +1,13 @@ import { UNIWIND_PLATFORM_VARIABLES, UNIWIND_THEME_VARIABLES } from '@/common/consts' -import { Declaration, MediaQuery, Rule, transform } from 'lightningcss' -import { Polyfills } from '../types' +import type { Declaration, MediaQuery, Rule } from 'lightningcss' +import { transform } from 'lightningcss' +import type { Polyfills } from '../types' import { Color } from './color' import { CSS } from './css' import { Functions } from './functions' import { MQ } from './mq' import { RN } from './rn' -import { ProcessMetaValues } from './types' +import type { ProcessMetaValues } from './types' import { Units } from './units' import { Var } from './var' diff --git a/packages/uniwind/src/bundler/css-processor/types.ts b/packages/uniwind/src/bundler/css-processor/types.ts index 50846300..2bbcd97e 100644 --- a/packages/uniwind/src/bundler/css-processor/types.ts +++ b/packages/uniwind/src/bundler/css-processor/types.ts @@ -1,4 +1,4 @@ -import { ColorScheme, Orientation, Platform } from '@/common/consts' +import type { ColorScheme, Orientation, Platform } from '@/common/consts' import type { AbsoluteFontWeight, Declaration, diff --git a/packages/uniwind/src/bundler/css-processor/units.ts b/packages/uniwind/src/bundler/css-processor/units.ts index 0aae4416..212afda3 100644 --- a/packages/uniwind/src/bundler/css-processor/units.ts +++ b/packages/uniwind/src/bundler/css-processor/units.ts @@ -1,4 +1,4 @@ -import { DimensionPercentageFor_LengthValue, Length, LengthValue } from 'lightningcss' +import type { DimensionPercentageFor_LengthValue, Length, LengthValue } from 'lightningcss' import { Logger } from '../logger' import type { ProcessorBuilder } from './processor' diff --git a/packages/uniwind/src/bundler/css-processor/var.ts b/packages/uniwind/src/bundler/css-processor/var.ts index 5389a5a2..f5a8af36 100644 --- a/packages/uniwind/src/bundler/css-processor/var.ts +++ b/packages/uniwind/src/bundler/css-processor/var.ts @@ -1,4 +1,4 @@ -import { Variable } from 'lightningcss' +import type { Variable } from 'lightningcss' import type { ProcessorBuilder } from './processor' export class Var { diff --git a/packages/uniwind/src/bundler/css-visitor/function-visitor.ts b/packages/uniwind/src/bundler/css-visitor/function-visitor.ts index b96409d2..5ee91134 100644 --- a/packages/uniwind/src/bundler/css-visitor/function-visitor.ts +++ b/packages/uniwind/src/bundler/css-visitor/function-visitor.ts @@ -1,4 +1,4 @@ -import { Function as LightningCSSFunction, TokenOrValue } from 'lightningcss' +import type { Function as LightningCSSFunction, TokenOrValue } from 'lightningcss' const ONE_PX = { type: 'token', diff --git a/packages/uniwind/src/bundler/css-visitor/rule-visitor.ts b/packages/uniwind/src/bundler/css-visitor/rule-visitor.ts index edc8320a..0a45ae30 100644 --- a/packages/uniwind/src/bundler/css-visitor/rule-visitor.ts +++ b/packages/uniwind/src/bundler/css-visitor/rule-visitor.ts @@ -1,4 +1,4 @@ -import { ReturnedDeclaration, ReturnedMediaQuery, ReturnedRule, Rule, SelectorComponent } from 'lightningcss' +import type { ReturnedDeclaration, ReturnedMediaQuery, ReturnedRule, Rule, SelectorComponent } from 'lightningcss' type LightningRuleVisitor = Rule type LightningRuleVisitors = Partial< diff --git a/packages/uniwind/src/bundler/css-visitor/visitor.ts b/packages/uniwind/src/bundler/css-visitor/visitor.ts index 518aaa5d..163a3e7d 100644 --- a/packages/uniwind/src/bundler/css-visitor/visitor.ts +++ b/packages/uniwind/src/bundler/css-visitor/visitor.ts @@ -1,4 +1,4 @@ -import { CustomAtRules, Visitor } from 'lightningcss' +import type { CustomAtRules, Visitor } from 'lightningcss' import { FunctionVisitor } from './function-visitor' import { RuleVisitor } from './rule-visitor' diff --git a/packages/uniwind/src/components/ScopedTheme/ScopedTheme.native.tsx b/packages/uniwind/src/components/ScopedTheme/ScopedTheme.native.tsx index 2f49ecd8..f6389629 100644 --- a/packages/uniwind/src/components/ScopedTheme/ScopedTheme.native.tsx +++ b/packages/uniwind/src/components/ScopedTheme/ScopedTheme.native.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react' import { UniwindContext } from '../../core/context' -import { ThemeName, UniwindContextType } from '../../core/types' +import type { ThemeName, UniwindContextType } from '../../core/types' type ScopedThemeProps = { theme: ThemeName diff --git a/packages/uniwind/src/components/native/ActivityIndicator.tsx b/packages/uniwind/src/components/native/ActivityIndicator.tsx index 0c1820b2..4ced1c61 100644 --- a/packages/uniwind/src/components/native/ActivityIndicator.tsx +++ b/packages/uniwind/src/components/native/ActivityIndicator.tsx @@ -1,4 +1,5 @@ -import { ActivityIndicator as RNActivityIndicator, ActivityIndicatorProps } from 'react-native' +import type { ActivityIndicatorProps } from 'react-native' +import { ActivityIndicator as RNActivityIndicator } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/Button.tsx b/packages/uniwind/src/components/native/Button.tsx index 82714dd8..2c87afc2 100644 --- a/packages/uniwind/src/components/native/Button.tsx +++ b/packages/uniwind/src/components/native/Button.tsx @@ -1,4 +1,5 @@ -import { Button as RNButton, ButtonProps } from 'react-native' +import type { ButtonProps } from 'react-native' +import { Button as RNButton } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' diff --git a/packages/uniwind/src/components/native/FlatList.tsx b/packages/uniwind/src/components/native/FlatList.tsx index a194621e..af216074 100644 --- a/packages/uniwind/src/components/native/FlatList.tsx +++ b/packages/uniwind/src/components/native/FlatList.tsx @@ -1,4 +1,5 @@ -import { FlatList as RNFlatList, FlatListProps } from 'react-native' +import type { FlatListProps } from 'react-native' +import { FlatList as RNFlatList } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/Image.tsx b/packages/uniwind/src/components/native/Image.tsx index 8d34df16..22a7f963 100644 --- a/packages/uniwind/src/components/native/Image.tsx +++ b/packages/uniwind/src/components/native/Image.tsx @@ -1,4 +1,5 @@ -import { Image as RNImage, ImageProps } from 'react-native' +import type { ImageProps } from 'react-native' +import { Image as RNImage } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/ImageBackground.tsx b/packages/uniwind/src/components/native/ImageBackground.tsx index 18393491..4d5b5639 100644 --- a/packages/uniwind/src/components/native/ImageBackground.tsx +++ b/packages/uniwind/src/components/native/ImageBackground.tsx @@ -1,4 +1,5 @@ -import { ImageBackground as RNImageBackground, ImageBackgroundProps } from 'react-native' +import type { ImageBackgroundProps } from 'react-native' +import { ImageBackground as RNImageBackground } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/InputAccessoryView.tsx b/packages/uniwind/src/components/native/InputAccessoryView.tsx index fad2936c..62aa5005 100644 --- a/packages/uniwind/src/components/native/InputAccessoryView.tsx +++ b/packages/uniwind/src/components/native/InputAccessoryView.tsx @@ -1,5 +1,6 @@ -import { ForwardedRef } from 'react' -import { InputAccessoryView as RNInputAccessoryView, InputAccessoryViewProps } from 'react-native' +import type { ForwardedRef } from 'react' +import type { InputAccessoryViewProps } from 'react-native' +import { InputAccessoryView as RNInputAccessoryView } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/KeyboardAvoidingView.tsx b/packages/uniwind/src/components/native/KeyboardAvoidingView.tsx index 045eb8cf..89038dea 100644 --- a/packages/uniwind/src/components/native/KeyboardAvoidingView.tsx +++ b/packages/uniwind/src/components/native/KeyboardAvoidingView.tsx @@ -1,4 +1,5 @@ -import { KeyboardAvoidingView as RNKeyboardAvoidingView, KeyboardAvoidingViewProps } from 'react-native' +import type { KeyboardAvoidingViewProps } from 'react-native' +import { KeyboardAvoidingView as RNKeyboardAvoidingView } from 'react-native' import { copyComponentProperties } from '../utils' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/Modal.tsx b/packages/uniwind/src/components/native/Modal.tsx index f35651b5..64004369 100644 --- a/packages/uniwind/src/components/native/Modal.tsx +++ b/packages/uniwind/src/components/native/Modal.tsx @@ -1,4 +1,5 @@ -import { Modal as RNModal, ModalProps } from 'react-native' +import type { ModalProps } from 'react-native' +import { Modal as RNModal } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/Pressable.tsx b/packages/uniwind/src/components/native/Pressable.tsx index 73b499f7..f23dc005 100644 --- a/packages/uniwind/src/components/native/Pressable.tsx +++ b/packages/uniwind/src/components/native/Pressable.tsx @@ -1,4 +1,5 @@ -import { Pressable as RNPressable, PressableProps } from 'react-native' +import type { PressableProps } from 'react-native' +import { Pressable as RNPressable } from 'react-native' import { useUniwindContext } from '../../core/context' import { UniwindStore } from '../../core/native' import { copyComponentProperties } from '../utils' diff --git a/packages/uniwind/src/components/native/RefreshControl.tsx b/packages/uniwind/src/components/native/RefreshControl.tsx index c22bed8c..b6d11a94 100644 --- a/packages/uniwind/src/components/native/RefreshControl.tsx +++ b/packages/uniwind/src/components/native/RefreshControl.tsx @@ -1,4 +1,5 @@ -import { RefreshControl as RNRefreshControl, RefreshControlProps } from 'react-native' +import type { RefreshControlProps } from 'react-native' +import { RefreshControl as RNRefreshControl } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/SafeAreaView.tsx b/packages/uniwind/src/components/native/SafeAreaView.tsx index 99b4e15f..0715d717 100644 --- a/packages/uniwind/src/components/native/SafeAreaView.tsx +++ b/packages/uniwind/src/components/native/SafeAreaView.tsx @@ -1,4 +1,5 @@ -import { SafeAreaView as RNSafeAreaView, ViewProps } from 'react-native' +import type { ViewProps } from 'react-native' +import { SafeAreaView as RNSafeAreaView } from 'react-native' import { copyComponentProperties } from '../utils' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/ScrollView.tsx b/packages/uniwind/src/components/native/ScrollView.tsx index d2ce2a56..817fa252 100644 --- a/packages/uniwind/src/components/native/ScrollView.tsx +++ b/packages/uniwind/src/components/native/ScrollView.tsx @@ -1,4 +1,5 @@ -import { ScrollView as RNScrollView, ScrollViewProps } from 'react-native' +import type { ScrollViewProps } from 'react-native' +import { ScrollView as RNScrollView } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/SectionList.tsx b/packages/uniwind/src/components/native/SectionList.tsx index a3e97d49..4a3d809b 100644 --- a/packages/uniwind/src/components/native/SectionList.tsx +++ b/packages/uniwind/src/components/native/SectionList.tsx @@ -1,4 +1,5 @@ -import { SectionList as RNSectionList, SectionListProps } from 'react-native' +import type { SectionListProps } from 'react-native' +import { SectionList as RNSectionList } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/Switch.tsx b/packages/uniwind/src/components/native/Switch.tsx index c7bc52a6..ce7d4ada 100644 --- a/packages/uniwind/src/components/native/Switch.tsx +++ b/packages/uniwind/src/components/native/Switch.tsx @@ -1,5 +1,6 @@ -import { Switch as RNSwitch, SwitchProps } from 'react-native' -import { ComponentState } from '../../core/types' +import type { SwitchProps } from 'react-native' +import { Switch as RNSwitch } from 'react-native' +import type { ComponentState } from '../../core/types' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/Text.tsx b/packages/uniwind/src/components/native/Text.tsx index 4b27f0c0..5d375a6d 100644 --- a/packages/uniwind/src/components/native/Text.tsx +++ b/packages/uniwind/src/components/native/Text.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' -import { Text as RNText, TextProps } from 'react-native' -import { ComponentState } from '../../core/types' +import type { TextProps } from 'react-native' +import { Text as RNText } from 'react-native' +import type { ComponentState } from '../../core/types' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/TextInput.tsx b/packages/uniwind/src/components/native/TextInput.tsx index 9e5172d7..61fd0599 100644 --- a/packages/uniwind/src/components/native/TextInput.tsx +++ b/packages/uniwind/src/components/native/TextInput.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' -import { TextInput as RNTextInput, TextInputProps } from 'react-native' -import { ComponentState } from '../../core/types' +import type { TextInputProps } from 'react-native' +import { TextInput as RNTextInput } from 'react-native' +import type { ComponentState } from '../../core/types' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/TouchableHighlight.tsx b/packages/uniwind/src/components/native/TouchableHighlight.tsx index b393cf8d..da211ce8 100644 --- a/packages/uniwind/src/components/native/TouchableHighlight.tsx +++ b/packages/uniwind/src/components/native/TouchableHighlight.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' -import { TouchableHighlight as RNTouchableHighlight, TouchableHighlightProps } from 'react-native' -import { ComponentState } from '../../core/types' +import type { TouchableHighlightProps } from 'react-native' +import { TouchableHighlight as RNTouchableHighlight } from 'react-native' +import type { ComponentState } from '../../core/types' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/TouchableNativeFeedback.tsx b/packages/uniwind/src/components/native/TouchableNativeFeedback.tsx index ca35768e..7c320388 100644 --- a/packages/uniwind/src/components/native/TouchableNativeFeedback.tsx +++ b/packages/uniwind/src/components/native/TouchableNativeFeedback.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' -import { TouchableNativeFeedback as RNTouchableNativeFeedback, TouchableNativeFeedbackProps } from 'react-native' -import { ComponentState } from '../../core/types' +import type { TouchableNativeFeedbackProps } from 'react-native' +import { TouchableNativeFeedback as RNTouchableNativeFeedback } from 'react-native' +import type { ComponentState } from '../../core/types' import { copyComponentProperties } from '../utils' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/TouchableOpacity.tsx b/packages/uniwind/src/components/native/TouchableOpacity.tsx index 7d0e2082..12680ae6 100644 --- a/packages/uniwind/src/components/native/TouchableOpacity.tsx +++ b/packages/uniwind/src/components/native/TouchableOpacity.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' -import { TouchableOpacity as RNTouchableOpacity, TouchableOpacityProps } from 'react-native' -import { ComponentState } from '../../core/types' +import type { TouchableOpacityProps } from 'react-native' +import { TouchableOpacity as RNTouchableOpacity } from 'react-native' +import type { ComponentState } from '../../core/types' import { copyComponentProperties } from '../utils' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/TouchableWithoutFeedback.tsx b/packages/uniwind/src/components/native/TouchableWithoutFeedback.tsx index 6b465856..6b325b4a 100644 --- a/packages/uniwind/src/components/native/TouchableWithoutFeedback.tsx +++ b/packages/uniwind/src/components/native/TouchableWithoutFeedback.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' -import { TouchableWithoutFeedback as RNTouchableWithoutFeedback, TouchableWithoutFeedbackProps } from 'react-native' -import { ComponentState } from '../../core/types' +import type { TouchableWithoutFeedbackProps } from 'react-native' +import { TouchableWithoutFeedback as RNTouchableWithoutFeedback } from 'react-native' +import type { ComponentState } from '../../core/types' import { copyComponentProperties } from '../utils' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/View.tsx b/packages/uniwind/src/components/native/View.tsx index 622a2f2f..a4412153 100644 --- a/packages/uniwind/src/components/native/View.tsx +++ b/packages/uniwind/src/components/native/View.tsx @@ -1,4 +1,5 @@ -import { View as RNView, ViewProps } from 'react-native' +import type { ViewProps } from 'react-native' +import { View as RNView } from 'react-native' import { copyComponentProperties } from '../utils' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/VirtualizedList.tsx b/packages/uniwind/src/components/native/VirtualizedList.tsx index 922a7b85..b32ae995 100644 --- a/packages/uniwind/src/components/native/VirtualizedList.tsx +++ b/packages/uniwind/src/components/native/VirtualizedList.tsx @@ -1,4 +1,5 @@ -import { VirtualizedList as RNVirtualizedList, VirtualizedListProps } from 'react-native' +import type { VirtualizedListProps } from 'react-native' +import { VirtualizedList as RNVirtualizedList } from 'react-native' import { copyComponentProperties } from '../utils' import { useAccentColor } from './useAccentColor' import { useStyle } from './useStyle' diff --git a/packages/uniwind/src/components/native/useAccentColor.ts b/packages/uniwind/src/components/native/useAccentColor.ts index f9ce9604..45370640 100644 --- a/packages/uniwind/src/components/native/useAccentColor.ts +++ b/packages/uniwind/src/components/native/useAccentColor.ts @@ -1,6 +1,6 @@ import { isDefined } from '../../common/utils' import { Logger } from '../../core/logger' -import { ComponentState } from '../../core/types' +import type { ComponentState } from '../../core/types' import { useStyle } from './useStyle' let warnedOnce = false diff --git a/packages/uniwind/src/components/native/useStyle.ts b/packages/uniwind/src/components/native/useStyle.ts index cfea356d..d7b8e866 100644 --- a/packages/uniwind/src/components/native/useStyle.ts +++ b/packages/uniwind/src/components/native/useStyle.ts @@ -2,7 +2,7 @@ import { useLayoutEffect, useReducer } from 'react' import { useUniwindContext } from '../../core/context' import { UniwindListener } from '../../core/listener' import { UniwindStore } from '../../core/native' -import { ComponentState } from '../../core/types' +import type { ComponentState } from '../../core/types' export const useStyle = (className: string | undefined, componentProps: Record, state?: ComponentState) => { 'use no memo' diff --git a/packages/uniwind/src/components/web/ActivityIndicator.tsx b/packages/uniwind/src/components/web/ActivityIndicator.tsx index d78dbe1a..d7a6aa2c 100644 --- a/packages/uniwind/src/components/web/ActivityIndicator.tsx +++ b/packages/uniwind/src/components/web/ActivityIndicator.tsx @@ -1,4 +1,5 @@ -import { ActivityIndicator as RNActivityIndicator, ActivityIndicatorProps } from 'react-native' +import type { ActivityIndicatorProps } from 'react-native' +import { ActivityIndicator as RNActivityIndicator } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/Button.tsx b/packages/uniwind/src/components/web/Button.tsx index 4dff979a..2685ff0c 100644 --- a/packages/uniwind/src/components/web/Button.tsx +++ b/packages/uniwind/src/components/web/Button.tsx @@ -1,4 +1,5 @@ -import { Button as RNButton, ButtonProps } from 'react-native' +import type { ButtonProps } from 'react-native' +import { Button as RNButton } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { useUniwindAccent } from './useUniwindAccent' diff --git a/packages/uniwind/src/components/web/FlatList.tsx b/packages/uniwind/src/components/web/FlatList.tsx index e1e10046..8d933565 100644 --- a/packages/uniwind/src/components/web/FlatList.tsx +++ b/packages/uniwind/src/components/web/FlatList.tsx @@ -1,4 +1,5 @@ -import { FlatList as RNFlatList, FlatListProps } from 'react-native' +import type { FlatListProps } from 'react-native' +import { FlatList as RNFlatList } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/Image.tsx b/packages/uniwind/src/components/web/Image.tsx index c77d8e51..a2a5780b 100644 --- a/packages/uniwind/src/components/web/Image.tsx +++ b/packages/uniwind/src/components/web/Image.tsx @@ -1,4 +1,5 @@ -import { Image as RNImage, ImageProps } from 'react-native' +import type { ImageProps } from 'react-native' +import { Image as RNImage } from 'react-native' import { useResolveClassNames } from '../../hooks' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' diff --git a/packages/uniwind/src/components/web/ImageBackground.tsx b/packages/uniwind/src/components/web/ImageBackground.tsx index b082cd93..37ec2b0a 100644 --- a/packages/uniwind/src/components/web/ImageBackground.tsx +++ b/packages/uniwind/src/components/web/ImageBackground.tsx @@ -1,4 +1,5 @@ -import { ImageBackground as RNImageBackground, ImageBackgroundProps } from 'react-native' +import type { ImageBackgroundProps } from 'react-native' +import { ImageBackground as RNImageBackground } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/KeyboardAvoidingView.tsx b/packages/uniwind/src/components/web/KeyboardAvoidingView.tsx index 4b35656f..612d0ce7 100644 --- a/packages/uniwind/src/components/web/KeyboardAvoidingView.tsx +++ b/packages/uniwind/src/components/web/KeyboardAvoidingView.tsx @@ -1,4 +1,5 @@ -import { KeyboardAvoidingView as RNKeyboardAvoidingView, KeyboardAvoidingViewProps } from 'react-native' +import type { KeyboardAvoidingViewProps } from 'react-native' +import { KeyboardAvoidingView as RNKeyboardAvoidingView } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/Modal.tsx b/packages/uniwind/src/components/web/Modal.tsx index 25853ffc..a81d64bf 100644 --- a/packages/uniwind/src/components/web/Modal.tsx +++ b/packages/uniwind/src/components/web/Modal.tsx @@ -1,4 +1,5 @@ -import { Modal as RNModal, ModalProps } from 'react-native' +import type { ModalProps } from 'react-native' +import { Modal as RNModal } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/Pressable.tsx b/packages/uniwind/src/components/web/Pressable.tsx index d08c016b..f60ed79d 100644 --- a/packages/uniwind/src/components/web/Pressable.tsx +++ b/packages/uniwind/src/components/web/Pressable.tsx @@ -1,4 +1,5 @@ -import { Pressable as RNPressable, PressableProps } from 'react-native' +import type { PressableProps } from 'react-native' +import { Pressable as RNPressable } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/RefreshControl.tsx b/packages/uniwind/src/components/web/RefreshControl.tsx index 22f30dbd..3d1a2fbf 100644 --- a/packages/uniwind/src/components/web/RefreshControl.tsx +++ b/packages/uniwind/src/components/web/RefreshControl.tsx @@ -1,4 +1,5 @@ -import { RefreshControl as RNRefreshControl, RefreshControlProps } from 'react-native' +import type { RefreshControlProps } from 'react-native' +import { RefreshControl as RNRefreshControl } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/SafeAreaView.tsx b/packages/uniwind/src/components/web/SafeAreaView.tsx index b00692cb..90f66fcc 100644 --- a/packages/uniwind/src/components/web/SafeAreaView.tsx +++ b/packages/uniwind/src/components/web/SafeAreaView.tsx @@ -1,4 +1,5 @@ -import { SafeAreaView as RNSafeAreaView, ViewProps } from 'react-native' +import type { ViewProps } from 'react-native' +import { SafeAreaView as RNSafeAreaView } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/ScrollView.tsx b/packages/uniwind/src/components/web/ScrollView.tsx index 679466cd..d4a27608 100644 --- a/packages/uniwind/src/components/web/ScrollView.tsx +++ b/packages/uniwind/src/components/web/ScrollView.tsx @@ -1,4 +1,5 @@ -import { ScrollView as RNScrollView, ScrollViewProps } from 'react-native' +import type { ScrollViewProps } from 'react-native' +import { ScrollView as RNScrollView } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/SectionList.tsx b/packages/uniwind/src/components/web/SectionList.tsx index b62ca71b..762c48fa 100644 --- a/packages/uniwind/src/components/web/SectionList.tsx +++ b/packages/uniwind/src/components/web/SectionList.tsx @@ -1,4 +1,5 @@ -import { SectionList as RNSectionList, SectionListProps } from 'react-native' +import type { SectionListProps } from 'react-native' +import { SectionList as RNSectionList } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/Switch.tsx b/packages/uniwind/src/components/web/Switch.tsx index 760f751f..6f89cb8a 100644 --- a/packages/uniwind/src/components/web/Switch.tsx +++ b/packages/uniwind/src/components/web/Switch.tsx @@ -1,4 +1,5 @@ -import { Switch as RNSwitch, SwitchProps } from 'react-native' +import type { SwitchProps } from 'react-native' +import { Switch as RNSwitch } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/Text.tsx b/packages/uniwind/src/components/web/Text.tsx index 1714f781..5c48e966 100644 --- a/packages/uniwind/src/components/web/Text.tsx +++ b/packages/uniwind/src/components/web/Text.tsx @@ -1,4 +1,5 @@ -import { Text as RNText, TextProps } from 'react-native' +import type { TextProps } from 'react-native' +import { Text as RNText } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/TextInput.tsx b/packages/uniwind/src/components/web/TextInput.tsx index a4f4dca2..2cc2bb42 100644 --- a/packages/uniwind/src/components/web/TextInput.tsx +++ b/packages/uniwind/src/components/web/TextInput.tsx @@ -1,4 +1,5 @@ -import { TextInput as RNTextInput, TextInputProps } from 'react-native' +import type { TextInputProps } from 'react-native' +import { TextInput as RNTextInput } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/TouchableHighlight.tsx b/packages/uniwind/src/components/web/TouchableHighlight.tsx index c7fa451f..b7f3288d 100644 --- a/packages/uniwind/src/components/web/TouchableHighlight.tsx +++ b/packages/uniwind/src/components/web/TouchableHighlight.tsx @@ -1,4 +1,5 @@ -import { TouchableHighlight as RNTouchableHighlight, TouchableHighlightProps } from 'react-native' +import type { TouchableHighlightProps } from 'react-native' +import { TouchableHighlight as RNTouchableHighlight } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/TouchableOpacity.tsx b/packages/uniwind/src/components/web/TouchableOpacity.tsx index d4f99fe0..8fddd293 100644 --- a/packages/uniwind/src/components/web/TouchableOpacity.tsx +++ b/packages/uniwind/src/components/web/TouchableOpacity.tsx @@ -1,4 +1,5 @@ -import { TouchableOpacity as RNTouchableOpacity, TouchableOpacityProps } from 'react-native' +import type { TouchableOpacityProps } from 'react-native' +import { TouchableOpacity as RNTouchableOpacity } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/TouchableWithoutFeedback.tsx b/packages/uniwind/src/components/web/TouchableWithoutFeedback.tsx index 2fa826fb..b15d9cea 100644 --- a/packages/uniwind/src/components/web/TouchableWithoutFeedback.tsx +++ b/packages/uniwind/src/components/web/TouchableWithoutFeedback.tsx @@ -1,4 +1,5 @@ -import { TouchableWithoutFeedback as RNTouchableWithoutFeedback, TouchableWithoutFeedbackProps } from 'react-native' +import type { TouchableWithoutFeedbackProps } from 'react-native' +import { TouchableWithoutFeedback as RNTouchableWithoutFeedback } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/View.tsx b/packages/uniwind/src/components/web/View.tsx index 5a97b019..f8b1d42a 100644 --- a/packages/uniwind/src/components/web/View.tsx +++ b/packages/uniwind/src/components/web/View.tsx @@ -1,4 +1,5 @@ -import { View as RNView, ViewProps } from 'react-native' +import type { ViewProps } from 'react-native' +import { View as RNView } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/components/web/VirtualizedList.tsx b/packages/uniwind/src/components/web/VirtualizedList.tsx index 93f35756..10e67d47 100644 --- a/packages/uniwind/src/components/web/VirtualizedList.tsx +++ b/packages/uniwind/src/components/web/VirtualizedList.tsx @@ -1,4 +1,5 @@ -import { VirtualizedList as RNVirtualizedList, VirtualizedListProps } from 'react-native' +import type { VirtualizedListProps } from 'react-native' +import { VirtualizedList as RNVirtualizedList } from 'react-native' import { copyComponentProperties } from '../utils' import { generateDataSet } from './generateDataSet' import { toRNWClassName } from './rnw' diff --git a/packages/uniwind/src/core/config/config.common.ts b/packages/uniwind/src/core/config/config.common.ts index 897adb26..0bdaa140 100644 --- a/packages/uniwind/src/core/config/config.common.ts +++ b/packages/uniwind/src/core/config/config.common.ts @@ -1,8 +1,10 @@ -import { Appearance, Insets, Platform } from 'react-native' +import type { Insets } from 'react-native' +import { Appearance, Platform } from 'react-native' import { ColorScheme, StyleDependency } from '../../common/consts' -import { GetCSSVariable, getCSSVariable } from '../../hooks/useCSSVariable/useCSSVariable' +import type { GetCSSVariable } from '../../hooks/useCSSVariable/useCSSVariable' +import { getCSSVariable } from '../../hooks/useCSSVariable/useCSSVariable' import { UniwindListener } from '../listener' -import { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types' +import type { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types' const SYSTEM_THEME = 'system' as const // Platform.constants is not defined in RNW diff --git a/packages/uniwind/src/core/config/config.native.ts b/packages/uniwind/src/core/config/config.native.ts index a5eaef78..fb54a3cc 100644 --- a/packages/uniwind/src/core/config/config.native.ts +++ b/packages/uniwind/src/core/config/config.native.ts @@ -1,10 +1,10 @@ import { formatHex, formatHex8, parse } from 'culori' -import { Insets } from 'react-native' +import type { Insets } from 'react-native' import { StyleDependency } from '../../common/consts' import { UniwindListener } from '../listener' import { Logger } from '../logger' import { UniwindStore } from '../native' -import { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types' +import type { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types' import { UniwindConfigBuilder as UniwindConfigBuilderBase } from './config.common' class UniwindConfigBuilder extends UniwindConfigBuilderBase { diff --git a/packages/uniwind/src/core/config/config.ts b/packages/uniwind/src/core/config/config.ts index bda1e851..e6f5a7fd 100644 --- a/packages/uniwind/src/core/config/config.ts +++ b/packages/uniwind/src/core/config/config.ts @@ -2,7 +2,7 @@ import { StyleDependency } from '../../common/consts' import { arrayEquals } from '../../common/utils' import { UniwindListener } from '../listener' import { Logger } from '../logger' -import { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types' +import type { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types' import { getWebVariable } from '../web' import { UniwindConfigBuilder as UniwindConfigBuilderBase } from './config.common' diff --git a/packages/uniwind/src/core/native/store.ts b/packages/uniwind/src/core/native/store.ts index b334f6a9..01b5951f 100644 --- a/packages/uniwind/src/core/native/store.ts +++ b/packages/uniwind/src/core/native/store.ts @@ -1,7 +1,7 @@ import { Dimensions, Platform } from 'react-native' import { Orientation, Platform as UniwindPlatform, StyleDependency, UNIWIND_PLATFORM_VARIABLES, UNIWIND_THEME_VARIABLES } from '../../common/consts' import { UniwindListener } from '../listener' -import { ComponentState, GenerateStyleSheetsCallback, RNStyle, Style, StyleSheets, ThemeName, UniwindContextType } from '../types' +import type { ComponentState, GenerateStyleSheetsCallback, RNStyle, Style, StyleSheets, ThemeName, UniwindContextType } from '../types' import { cloneWithAccessors } from './native-utils' import { parseBoxShadow, parseFontVariant, parseTextShadowMutation, parseTransformsMutation, resolveGradient } from './parsers' import { UniwindRuntime } from './runtime' diff --git a/packages/uniwind/src/core/types.ts b/packages/uniwind/src/core/types.ts index 467e33f2..0fb3ce04 100644 --- a/packages/uniwind/src/core/types.ts +++ b/packages/uniwind/src/core/types.ts @@ -1,6 +1,6 @@ import React from 'react' import type { ImageStyle, StyleProp, TextStyle, ViewStyle } from 'react-native' -import { ColorScheme, Orientation, StyleDependency } from '../common/consts' +import type { ColorScheme, Orientation, StyleDependency } from '../common/consts' import type { UniwindContext } from './context' export type Style = { diff --git a/packages/uniwind/src/core/web/getWebStyles.ts b/packages/uniwind/src/core/web/getWebStyles.ts index 92c081d5..f7ac0580 100644 --- a/packages/uniwind/src/core/web/getWebStyles.ts +++ b/packages/uniwind/src/core/web/getWebStyles.ts @@ -1,5 +1,5 @@ import { generateDataSet } from '../../components/web/generateDataSet' -import { RNStyle, UniwindContextType } from '../types' +import type { RNStyle, UniwindContextType } from '../types' import { CSSListener } from './cssListener' import { parseCSSValue } from './parseCSSValue' diff --git a/packages/uniwind/src/hoc/types.ts b/packages/uniwind/src/hoc/types.ts index 8d9421f6..2ef08e52 100644 --- a/packages/uniwind/src/hoc/types.ts +++ b/packages/uniwind/src/hoc/types.ts @@ -1,5 +1,5 @@ -import { ComponentProps, ComponentPropsWithRef } from 'react' -import { RNStyle } from '../core/types' +import type { ComponentProps, ComponentPropsWithRef } from 'react' +import type { RNStyle } from '../core/types' export type AnyObject = Record diff --git a/packages/uniwind/src/hoc/withUniwind.native.tsx b/packages/uniwind/src/hoc/withUniwind.native.tsx index 139ad000..8f613b89 100644 --- a/packages/uniwind/src/hoc/withUniwind.native.tsx +++ b/packages/uniwind/src/hoc/withUniwind.native.tsx @@ -1,11 +1,12 @@ -import { ComponentProps, useLayoutEffect, useReducer } from 'react' -import { StyleDependency } from '../common/consts' +import type { ComponentProps } from 'react' +import { useLayoutEffect, useReducer } from 'react' +import type { StyleDependency } from '../common/consts' import { isDefined } from '../common/utils' import { useUniwindContext } from '../core/context' import { UniwindListener } from '../core/listener' import { Logger } from '../core/logger' import { UniwindStore } from '../core/native' -import { AnyObject, Component, OptionMapping, WithUniwind } from './types' +import type { AnyObject, Component, OptionMapping, WithUniwind } from './types' import { classToColor, classToStyle, isClassProperty, isColorClassProperty, isStyleProperty } from './withUniwindUtils' let warnedOnce = false diff --git a/packages/uniwind/src/hoc/withUniwind.tsx b/packages/uniwind/src/hoc/withUniwind.tsx index fdad155e..533fc7fb 100644 --- a/packages/uniwind/src/hoc/withUniwind.tsx +++ b/packages/uniwind/src/hoc/withUniwind.tsx @@ -1,10 +1,11 @@ -import { ComponentProps, useLayoutEffect, useReducer } from 'react' +import type { ComponentProps } from 'react' +import { useLayoutEffect, useReducer } from 'react' import { isDefined } from '../common/utils' import { generateDataSet } from '../components/web/generateDataSet' import { useUniwindContext } from '../core/context' import { Logger } from '../core/logger' import { CSSListener, formatColor, getWebStyles } from '../core/web' -import { AnyObject, Component, OptionMapping, WithUniwind } from './types' +import type { AnyObject, Component, OptionMapping, WithUniwind } from './types' import { classToColor, classToStyle, isClassProperty, isColorClassProperty, isStyleProperty } from './withUniwindUtils' let warnedOnce = false diff --git a/packages/uniwind/src/hooks/useCSSVariable/getVariableValue.native.ts b/packages/uniwind/src/hooks/useCSSVariable/getVariableValue.native.ts index ab7e18ac..dae0d663 100644 --- a/packages/uniwind/src/hooks/useCSSVariable/getVariableValue.native.ts +++ b/packages/uniwind/src/hooks/useCSSVariable/getVariableValue.native.ts @@ -1,5 +1,5 @@ import { UniwindRuntime, UniwindStore } from '../../core/native' -import { UniwindContextType } from '../../core/types' +import type { UniwindContextType } from '../../core/types' export const getVariableValue = (name: string, uniwindContext: UniwindContextType) => UniwindStore.vars[uniwindContext.scopedTheme ?? UniwindRuntime.currentThemeName]?.[name] diff --git a/packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts b/packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts index 70f70e79..46b3135a 100644 --- a/packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts +++ b/packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts @@ -4,7 +4,7 @@ import { arrayEquals } from '../../common/utils' import { useUniwindContext } from '../../core/context' import { UniwindListener } from '../../core/listener' import { Logger } from '../../core/logger' -import { UniwindContextType } from '../../core/types' +import type { UniwindContextType } from '../../core/types' import { getVariableValue } from './getVariableValue' let warned = false diff --git a/packages/uniwind/src/hooks/useResolveClassNames.ts b/packages/uniwind/src/hooks/useResolveClassNames.ts index 83b99d01..4fa23ac5 100644 --- a/packages/uniwind/src/hooks/useResolveClassNames.ts +++ b/packages/uniwind/src/hooks/useResolveClassNames.ts @@ -1,6 +1,6 @@ import { useLayoutEffect, useReducer } from 'react' import { useUniwindContext } from '../core/context' -import { RNStyle } from '../core/types' +import type { RNStyle } from '../core/types' import { CSSListener, getWebStyles } from '../core/web' const emptyState = {} as RNStyle diff --git a/packages/uniwind/src/hooks/useUniwind.ts b/packages/uniwind/src/hooks/useUniwind.ts index d5fa218b..e96f4046 100644 --- a/packages/uniwind/src/hooks/useUniwind.ts +++ b/packages/uniwind/src/hooks/useUniwind.ts @@ -3,7 +3,7 @@ import { StyleDependency } from '../common/consts' import { Uniwind } from '../core' import { useUniwindContext } from '../core/context' import { UniwindListener } from '../core/listener' -import { ThemeName } from '../core/types' +import type { ThemeName } from '../core/types' export const useUniwind = (): { theme: ThemeName; hasAdaptiveThemes: boolean } => { const uniwindContext = useUniwindContext() From f823b7cbd0c209f60abe06287271fff0522f36b1 Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Thu, 7 May 2026 15:02:26 +0200 Subject: [PATCH 09/13] chore: minor corrections --- context.md | 1 + packages/uniwind/src/bundler/adapters/metro/metro.ts | 2 +- packages/uniwind/src/bundler/artifacts/css/themes.ts | 2 +- packages/uniwind/src/bundler/config.ts | 7 ++++++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/context.md b/context.md index df874c84..46d5b0d9 100644 --- a/context.md +++ b/context.md @@ -102,6 +102,7 @@ Compilation flow: - `compileWebCSS` runs Lightning CSS with `UniwindCSSVisitor` and returns CSS. - `compileNativeCSS` runs `ProcessorBuilder`, serializes variables, scoped variables, and native stylesheet metadata into JS source. - `UniwindBundlerConfig.generateArtifacts` writes CSS artifacts and generated theme typings. +- Internal package aliases such as `@/*` are only safe inside `packages/uniwind/src/bundler`. Bundler files are built and transformed to JS, but runtime/component/hook/HOC files are published directly as `.ts`/`.tsx` React Native entrypoints, so aliases in those files are not rewritten. Metro integration: diff --git a/packages/uniwind/src/bundler/adapters/metro/metro.ts b/packages/uniwind/src/bundler/adapters/metro/metro.ts index ffa882c1..e78367e5 100644 --- a/packages/uniwind/src/bundler/adapters/metro/metro.ts +++ b/packages/uniwind/src/bundler/adapters/metro/metro.ts @@ -9,7 +9,7 @@ export const withUniwindConfig = ( config: T, uniwindConfig: UniwindConfig, ): T => { - const bundlerConfig = UniwindBundlerConfig.fromMetroConfig(uniwindConfig, Platform.Native) + const bundlerConfig = UniwindBundlerConfig.fromMetroConfig(uniwindConfig) patchMetroGraphToSupportUncachedModules() return { diff --git a/packages/uniwind/src/bundler/artifacts/css/themes.ts b/packages/uniwind/src/bundler/artifacts/css/themes.ts index c04ab2d1..c160e3d1 100644 --- a/packages/uniwind/src/bundler/artifacts/css/themes.ts +++ b/packages/uniwind/src/bundler/artifacts/css/themes.ts @@ -1,8 +1,8 @@ +import { Logger } from '@/bundler/logger' import { compile } from '@tailwindcss/node' import fs from 'fs' import { transform } from 'lightningcss' import path from 'path' -import { Logger } from '../../logger' const readFileSafe = (filePath: string) => { try { diff --git a/packages/uniwind/src/bundler/config.ts b/packages/uniwind/src/bundler/config.ts index 75314f3b..1a4ff27b 100644 --- a/packages/uniwind/src/bundler/config.ts +++ b/packages/uniwind/src/bundler/config.ts @@ -3,11 +3,16 @@ import { buildDtsFile } from '@/bundler/artifacts/dts' import { UniwindCSSVisitor } from '@/bundler/css-visitor' import type { UniwindConfig, UniwindMetroConfig } from '@/bundler/types' import { Platform } from '@/common/consts' +import { isDefined } from '@/common/utils' import path from 'path' export class UniwindBundlerConfig { - static fromMetroConfig(config: UniwindMetroConfig, platform: string | null | undefined) { + static fromMetroConfig(config: UniwindMetroConfig, platform?: string | null | undefined) { const getPlatform = () => { + if (!isDefined(platform)) { + return Platform.Native + } + if (!config.isTV) { return platform as Platform } From a0f5cc80ef260a2eefda9e5280f913ef1e104602 Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Fri, 8 May 2026 08:26:00 +0200 Subject: [PATCH 10/13] docs: update context.md --- context.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/context.md b/context.md index 46d5b0d9..e4827595 100644 --- a/context.md +++ b/context.md @@ -79,7 +79,7 @@ Web runtime: Shared runtime: -- `Uniwind.setTheme(theme | 'system')` switches explicit themes or returns to system adaptive light/dark. +- `Uniwind.setTheme(theme | 'system')` switches explicit themes or returns to system-adaptive light/dark. - `Uniwind.currentTheme` and `Uniwind.hasAdaptiveThemes` back `useUniwind`. - `Uniwind.updateCSSVariables(theme, variables)` updates theme variables and notifies variable subscribers. - `Uniwind.updateInsets(insets)` is native-only behavior and updates safe-area-style runtime values. @@ -115,7 +115,7 @@ Metro integration: Vite integration: -- `uniwind(config)` returns a pre Vite plugin. +- `uniwind(config)` returns a pre-Vite plugin. - Vite aliases `react-native` to Uniwind web components, except imports from Uniwind internals resolve back to `react-native-web`. - Vite replaces RNW `createOrderedCSSStyleSheet` with Uniwind's ordered stylesheet implementation. - Vite uses Lightning CSS with `UniwindCSSVisitor`. @@ -127,8 +127,8 @@ Native processing converts Tailwind-generated CSS into metadata-rich style recor Important concepts: -- A `Style` record stores entries, breakpoint bounds, orientation, theme, RTL, native flag, dependencies, source index, class name, important properties, selector complexity, pseudo states, and data attributes. -- CSS variables live in `vars`; theme and platform scoped variables live in `scopedVars` with internal prefixes. +- A `Style` record stores entries, breakpoint bounds, orientation, theme, RTL, native flag, dependencies, source index, class name, important properties, selector complexity, pseudo-states, and data attributes. +- CSS variables live in `vars`; theme and platform-scoped variables live in `scopedVars` with internal prefixes. - The processor treats declarations under `:root` or outside class rules as variables. - Theme variants are recognized from known theme names. - Data attribute variants support boolean `data-x` and exact `data-x="value"` matching against component props. From 3aec8bbbb602ad581f64fee764049561005daf70 Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Fri, 15 May 2026 08:53:15 +0200 Subject: [PATCH 11/13] test: fix meta test after merge --- .../tests/native/styles-parsing/meta.test.ts | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/packages/uniwind/tests/native/styles-parsing/meta.test.ts b/packages/uniwind/tests/native/styles-parsing/meta.test.ts index 5921701d..958f8983 100644 --- a/packages/uniwind/tests/native/styles-parsing/meta.test.ts +++ b/packages/uniwind/tests/native/styles-parsing/meta.test.ts @@ -1,26 +1,17 @@ -import { readFileSync } from 'fs' -import { resolve } from 'path' -import { Platform } from '../../../src/common/consts' +import { UniwindBundlerConfig } from '../../../src/bundler/config' +import { compileCSS } from '../../../src/bundler/css-compiler' +import { Platform, StyleDependency } from '../../../src/common/consts' import { StyleSheets } from '../../../src/core/types' -import { compileVirtual } from '../../../src/metro/compileVirtual' -import { StyleDependency } from '../../../src/types' type CompiledResult = { stylesheet: StyleSheets } -const compileMetadata = async (candidates: Array): Promise => { - const cssPath = resolve('./tests/test.css') - const css = readFileSync(cssPath, 'utf-8') - const virtualCode = await compileVirtual({ - css, - cssPath, - debug: false, - platform: Platform.iOS, - themes: ['light', 'dark'], - polyfills: undefined, - candidates, - }) +const compileMetadata = async (): Promise => { + const bundlerConfig = UniwindBundlerConfig.fromMetroConfig({ + cssEntryFile: './tests/test.css', + }, Platform.iOS) + const virtualCode = await compileCSS(bundlerConfig) // oxlint-disable-next-line no-unused-vars const rt = {} @@ -31,7 +22,7 @@ const compileMetadata = async (candidates: Array): Promise { test('Theme Style Dependency', async () => { - const { stylesheet } = await compileMetadata(['bg-background', 'bg-foreground']) + const { stylesheet } = await compileMetadata() expect(stylesheet['bg-background'][0].dependencies).toContain(StyleDependency.Theme) expect(stylesheet['bg-foreground'][0].dependencies).toContain(StyleDependency.Theme) From 211ddb7d46e68442d9be5322378c1080974ca45b Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Fri, 15 May 2026 08:53:54 +0200 Subject: [PATCH 12/13] chore: lint warning --- packages/uniwind/src/bundler/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/uniwind/src/bundler/config.ts b/packages/uniwind/src/bundler/config.ts index 1a4ff27b..1f7409d7 100644 --- a/packages/uniwind/src/bundler/config.ts +++ b/packages/uniwind/src/bundler/config.ts @@ -7,7 +7,7 @@ import { isDefined } from '@/common/utils' import path from 'path' export class UniwindBundlerConfig { - static fromMetroConfig(config: UniwindMetroConfig, platform?: string | null | undefined) { + static fromMetroConfig(config: UniwindMetroConfig, platform?: string | null) { const getPlatform = () => { if (!isDefined(platform)) { return Platform.Native From 286d96ea50c587289236c989a9f1557304ecb259 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 15 May 2026 06:59:46 +0000 Subject: [PATCH 13/13] chore: release v1.6.7-beta.0 --- packages/uniwind/CHANGELOG.md | 40 ++++++++++++++++++++++++++++++++++- packages/uniwind/package.json | 2 +- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/uniwind/CHANGELOG.md b/packages/uniwind/CHANGELOG.md index d58f7185..a9a2959e 100644 --- a/packages/uniwind/CHANGELOG.md +++ b/packages/uniwind/CHANGELOG.md @@ -1,4 +1,28 @@ -## What's Changed in 1.6.5 +## What's Changed in 1.6.7-beta.0 + + + +### ๐Ÿ“ฆ Other +* Merge branch 'main' into major-refactor + + +**Full Changelog**: https://github.com/uni-stack/uniwind/compare/v1.6.6-beta.0...v1.6.7-beta.0## What's Changed in 1.6.6-beta.0 + + + +### ๐Ÿงช Testing +* fix meta test after merge + + +### ๐Ÿ  Chores +* lint warning + + +### ๐Ÿ“ฆ Other +* Merge branch 'main' into major-refactor + + +**Full Changelog**: https://github.com/uni-stack/uniwind/compare/v1.6.5...v1.6.6-beta.0## What's Changed in 1.6.5 @@ -26,6 +50,20 @@ * fix: remove deprecated push notification ios export by @Brentlok in [#516](https://github.com/uni-stack/uniwind/pull/516) +### ๐Ÿ”จ Refactoring +* refactored bundler code +* add import aliases and move vite to bundler/adapters + + +### ๐Ÿ  Chores +* minor corrections +* consistent type imports +* fs promise to read file for tailwind compilation +* add new line before reinit in vite adapter +* unused aliases +* remove unused + + **Full Changelog**: https://github.com/uni-stack/uniwind/compare/v1.6.3...v1.6.4## What's Changed in 1.6.3 diff --git a/packages/uniwind/package.json b/packages/uniwind/package.json index e7bec2a9..ee36d021 100644 --- a/packages/uniwind/package.json +++ b/packages/uniwind/package.json @@ -1,7 +1,7 @@ { "private": false, "name": "uniwind", - "version": "1.6.6-beta.0", + "version": "1.6.7-beta.0", "description": "The fastest Tailwind bindings for React Native", "homepage": "https://uniwind.dev", "author": "Unistack",