@colorye/react-native-css 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +198 -0
- package/crates/transformer/index.js +105 -0
- package/crates/transformer/transformer.darwin-arm64.node +0 -0
- package/crates/transformer/transformer.node +0 -0
- package/dist/babel.js +208 -0
- package/dist/exported-stylesheet.json +1 -0
- package/dist/features/build-transform.js +575 -0
- package/dist/features/css-calc.js +539 -0
- package/dist/features/css-media.js +77 -0
- package/dist/features/css-transform.js +426 -0
- package/dist/features/css-vars.js +153 -0
- package/dist/features/stylesheet.js +45 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.js +60 -0
- package/dist/interop.js +260 -0
- package/dist/transformer-runtime.js +274 -0
- package/dist/transformer.js +100 -0
- package/dist/utils/babel.js +363 -0
- package/dist/utils/css.js +263 -0
- package/dist/utils/helper.js +11 -0
- package/package.json +51 -0
- package/src/babel.js +271 -0
- package/src/exported-stylesheet.json +1 -0
- package/src/features/build-transform.js +536 -0
- package/src/features/css-calc.js +490 -0
- package/src/features/css-media.js +78 -0
- package/src/features/css-transform.js +446 -0
- package/src/features/css-vars.js +138 -0
- package/src/features/stylesheet.js +29 -0
- package/src/index.d.ts +89 -0
- package/src/index.js +29 -0
- package/src/interop.js +269 -0
- package/src/transformer-runtime.js +241 -0
- package/src/transformer.js +87 -0
- package/src/utils/babel.js +425 -0
- package/src/utils/css.js +221 -0
- package/src/utils/helper.js +3 -0
- package/types.d.ts +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# @colorye/react-native-css β‘οΈ
|
|
2
|
+
|
|
3
|
+
> High-performance, Rust SWCβpowered Tailwind CSS v4 and standard CSS compiler for React Native and Expo.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@colorye/react-native-css)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## π Why @colorye/react-native-css?
|
|
11
|
+
|
|
12
|
+
Modern React Native apps need the ergonomics of Tailwind CSS v4 and standard CSS without sacrificing runtime performance. `@colorye/react-native-css` compiles utility classes directly into **hoisted `StyleSheet.create` objects (`_rnStyles`)** using a native Rust SWC transform layer.
|
|
13
|
+
|
|
14
|
+
- π¦ **Rust SWC Compiler**: Transforms JSX at native speeds, hoisting static styles to `StyleSheet.create` with **zero runtime overhead**.
|
|
15
|
+
- πΊοΈ **SourceMap v3 Fidelity**: Full source mapping support for accurate line-and-column stack traces in Metro / React Native debugger.
|
|
16
|
+
- π¨ **Tailwind CSS v4 Native**: Full support for CSS-first config, `@theme`, `oklch()`, `lab()`, CSS custom properties (`var()`), and nested `calc()`.
|
|
17
|
+
- β‘ **Optimized Dynamic States**: Pseudo-classes like `active:`, `pressed:`, and `disabled:` compile to optimized React Native Pressable render callbacks.
|
|
18
|
+
- π¬ **Transition & Animation**: Support for `duration-`, `ease-`, and `delay-` utility mappings.
|
|
19
|
+
- π³ **Group States & Text Inheritance**: Native coordination for `group` / `group-active:` and CSS text style inheritance (`color`, `fontSize`, `fontWeight`, etc.).
|
|
20
|
+
- π **Component Interoperability**: First-class `cssInterop` and `remapProps` for third-party libraries (`FlashList`, `TrueSheet`, etc.).
|
|
21
|
+
- π **Multi-platform N-API Prebuilds**: Zero-setup binaries across macOS (Apple Silicon & Intel), Linux (GNU & musl, x64 & arm64), and Windows (x64 & arm64).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## βοΈ SOTA Comparison
|
|
26
|
+
|
|
27
|
+
| Feature / Metric | `@colorye/react-native-css` | NativeWind v4 | Unistyles 3.0 | Tamagui | Vanilla `StyleSheet` |
|
|
28
|
+
| :--- | :---: | :---: | :---: | :---: | :---: |
|
|
29
|
+
| **Styling Paradigm** | **Tailwind v4 / Modern CSS** | Tailwind v3/v4 | Custom StyleSheet DSL | Custom UI / Styled DSL | Plain JS Objects |
|
|
30
|
+
| **Compiler Engine** | **Rust (SWC + LightningCSS)** | Babel / LightningCSS | None (Pure C++ JSI) | Babel / Node AST | None |
|
|
31
|
+
| **Static Style Inlining** | **Hoisted `StyleSheet.create`** | Runtime Mapping | Runtime C++ Stylesheet | Compile-time flattening | Manual |
|
|
32
|
+
| **Tailwind v4 (@theme, oklch)** | **β
First-Class Native** | π‘ Requires plugins | β Custom tokens | β Custom config | β Manual |
|
|
33
|
+
| **Static Class Runtime Cost** | **0 ms** | Low-to-medium | Low (C++ JSI cache) | Low-to-zero | 0 ms |
|
|
34
|
+
| **Dynamic Pseudo-states** (`active:`, `disabled:`) | **Auto Pressable / JSX Transform** | Dynamic hooks / proxy | Runtime state bindings | Compiler variants | Manual state logic |
|
|
35
|
+
| **CSS Text Style Inheritance** | **Automatic (`InheritContext`)** | Web-only / explicit | Manual | Theme-based | Manual |
|
|
36
|
+
| **Third-Party Component Interop** | **`cssInterop` / `remapProps`** | `cssInterop` | Custom C++ wrappers | Custom styled wrappers | Manual `style` passing |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## π¦ Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install @colorye/react-native-css
|
|
44
|
+
# or
|
|
45
|
+
yarn add @colorye/react-native-css
|
|
46
|
+
# or
|
|
47
|
+
pnpm add @colorye/react-native-css
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## βοΈ Setup & Configuration
|
|
53
|
+
|
|
54
|
+
### 1. Metro Configuration (`metro.config.js`)
|
|
55
|
+
|
|
56
|
+
Wrap your Metro config or assign the custom CSS transformer:
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
const { getDefaultConfig } = require("expo/metro-config");
|
|
60
|
+
|
|
61
|
+
const config = getDefaultConfig(__dirname);
|
|
62
|
+
|
|
63
|
+
config.transformer = {
|
|
64
|
+
...config.transformer,
|
|
65
|
+
babelTransformerPath: require.resolve("@colorye/react-native-css/transformer"),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
module.exports = config;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 2. Babel Configuration (`babel.config.js`)
|
|
72
|
+
|
|
73
|
+
Add the Babel plugin pointing to your global stylesheet:
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
module.exports = function (api) {
|
|
77
|
+
api.cache(true);
|
|
78
|
+
return {
|
|
79
|
+
presets: ["babel-preset-expo"],
|
|
80
|
+
plugins: [
|
|
81
|
+
[
|
|
82
|
+
"@colorye/react-native-css/babel",
|
|
83
|
+
{
|
|
84
|
+
css: "./src/assets/styles/index.css",
|
|
85
|
+
paths: ["src/"],
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Tailwind CSS Setup (`src/assets/styles/index.css`)
|
|
94
|
+
|
|
95
|
+
Import Tailwind CSS v4 in your main CSS file:
|
|
96
|
+
|
|
97
|
+
```css
|
|
98
|
+
@import "tailwindcss";
|
|
99
|
+
|
|
100
|
+
@theme {
|
|
101
|
+
--color-primary: #0065d6;
|
|
102
|
+
--color-secondary: #0ea5e9;
|
|
103
|
+
--font-display: "Inter-Bold";
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## π TypeScript Support
|
|
110
|
+
|
|
111
|
+
Add the type definitions to your `env.d.ts` or `global.d.ts` for JSX `className` auto-completion on all React Native primitives:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
/// <reference types="@colorye/react-native-css/types" />
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## π‘ Usage Examples
|
|
120
|
+
|
|
121
|
+
### Basic Styling & Pseudo-classes
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { View, Text, Pressable } from "react-native";
|
|
125
|
+
|
|
126
|
+
export function UserCard() {
|
|
127
|
+
return (
|
|
128
|
+
<View className="p-4 bg-white rounded-2xl shadow-sm">
|
|
129
|
+
<Text className="text-xl font-bold text-slate-900">
|
|
130
|
+
React Native CSS
|
|
131
|
+
</Text>
|
|
132
|
+
<Pressable className="mt-4 px-4 py-2 bg-primary rounded-xl active:scale-95 active:opacity-80">
|
|
133
|
+
<Text className="text-white text-center font-medium">Get Started</Text>
|
|
134
|
+
</Pressable>
|
|
135
|
+
</View>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Group Hover / Active States
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { Pressable, View, Text } from "react-native";
|
|
144
|
+
|
|
145
|
+
export function GroupItem() {
|
|
146
|
+
return (
|
|
147
|
+
<Pressable className="group flex-row items-center p-3 rounded-lg bg-slate-100">
|
|
148
|
+
<View className="w-3 h-3 rounded-full bg-slate-400 group-active:bg-primary" />
|
|
149
|
+
<Text className="ml-3 text-slate-700 group-active:text-primary font-medium">
|
|
150
|
+
Click to Highlight
|
|
151
|
+
</Text>
|
|
152
|
+
</Pressable>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Third-Party Component Interop (`cssInterop`)
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import { FlashList } from "@shopify/flash-list";
|
|
161
|
+
import { cssInterop } from "@colorye/react-native-css";
|
|
162
|
+
|
|
163
|
+
export const StyledFlashList = cssInterop(FlashList, {
|
|
164
|
+
className: "style",
|
|
165
|
+
contentContainerClassName: "contentContainerStyle",
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Usage
|
|
169
|
+
<StyledFlashList
|
|
170
|
+
className="flex-1 bg-slate-50"
|
|
171
|
+
contentContainerClassName="p-4"
|
|
172
|
+
data={data}
|
|
173
|
+
renderItem={renderItem}
|
|
174
|
+
/>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## π€ Contributing
|
|
180
|
+
|
|
181
|
+
Contributions, issues, and feature requests are welcome!
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Build Rust native bindings
|
|
185
|
+
yarn build:native
|
|
186
|
+
|
|
187
|
+
# Build JS distribution
|
|
188
|
+
yarn build:js
|
|
189
|
+
|
|
190
|
+
# Run full build
|
|
191
|
+
yarn build
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## π License
|
|
197
|
+
|
|
198
|
+
MIT Β© [Rye Nguyen](https://github.com/ryenguyen7411)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const { existsSync, readFileSync } = require("fs");
|
|
2
|
+
const { join } = require("path");
|
|
3
|
+
|
|
4
|
+
const { platform, arch } = process;
|
|
5
|
+
|
|
6
|
+
let nativeBinding = null;
|
|
7
|
+
let loadError = null;
|
|
8
|
+
|
|
9
|
+
function isMusl() {
|
|
10
|
+
if (!process.report || typeof process.report.getReport !== "function") {
|
|
11
|
+
try {
|
|
12
|
+
const lddPath = require("child_process").execSync("which ldd").toString().trim();
|
|
13
|
+
return readFileSync(lddPath, "utf8").includes("musl");
|
|
14
|
+
} catch {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
const { glibcVersionRuntime } = process.report.getReport().header;
|
|
19
|
+
return !glibcVersionRuntime;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 1. Resolve candidate binary filename for current OS & architecture
|
|
24
|
+
function getCandidateFilenames() {
|
|
25
|
+
const candidates = [];
|
|
26
|
+
|
|
27
|
+
switch (platform) {
|
|
28
|
+
case "darwin":
|
|
29
|
+
if (arch === "arm64") {
|
|
30
|
+
candidates.push("transformer.darwin-arm64.node");
|
|
31
|
+
} else if (arch === "x64") {
|
|
32
|
+
candidates.push("transformer.darwin-x64.node");
|
|
33
|
+
}
|
|
34
|
+
candidates.push("transformer.darwin-universal.node");
|
|
35
|
+
break;
|
|
36
|
+
|
|
37
|
+
case "linux":
|
|
38
|
+
if (arch === "x64") {
|
|
39
|
+
if (isMusl()) {
|
|
40
|
+
candidates.push("transformer.linux-x64-musl.node");
|
|
41
|
+
} else {
|
|
42
|
+
candidates.push("transformer.linux-x64-gnu.node");
|
|
43
|
+
}
|
|
44
|
+
} else if (arch === "arm64") {
|
|
45
|
+
if (isMusl()) {
|
|
46
|
+
candidates.push("transformer.linux-arm64-musl.node");
|
|
47
|
+
} else {
|
|
48
|
+
candidates.push("transformer.linux-arm64-gnu.node");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
case "win32":
|
|
54
|
+
if (arch === "x64") {
|
|
55
|
+
candidates.push("transformer.win32-x64-msvc.node");
|
|
56
|
+
} else if (arch === "arm64") {
|
|
57
|
+
candidates.push("transformer.win32-arm64-msvc.node");
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case "android":
|
|
62
|
+
if (arch === "arm64") {
|
|
63
|
+
candidates.push("transformer.android-arm64.node");
|
|
64
|
+
} else if (arch === "arm") {
|
|
65
|
+
candidates.push("transformer.android-arm-eabi.node");
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Generic local fallback (built by `cargo build --release`)
|
|
71
|
+
candidates.push("transformer.node");
|
|
72
|
+
|
|
73
|
+
return candidates;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 2. Load the first matching candidate file from inside this package
|
|
77
|
+
for (const file of getCandidateFilenames()) {
|
|
78
|
+
const fullPath = join(__dirname, file);
|
|
79
|
+
if (existsSync(fullPath)) {
|
|
80
|
+
try {
|
|
81
|
+
nativeBinding = require(`./${file}`);
|
|
82
|
+
break;
|
|
83
|
+
} catch (e) {
|
|
84
|
+
loadError = e;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!nativeBinding) {
|
|
90
|
+
// If no candidate succeeded, try direct require of fallback
|
|
91
|
+
try {
|
|
92
|
+
nativeBinding = require("./transformer.node");
|
|
93
|
+
} catch (e) {
|
|
94
|
+
const errorMsg =
|
|
95
|
+
`Failed to load native binding for @colorye/react-native-css on ${platform}-${arch}.\n` +
|
|
96
|
+
`Ensure that transformer.node or transformer.${platform}-${arch}.node exists in ${__dirname}.\n` +
|
|
97
|
+
(loadError ? `Original error: ${loadError.message}` : "");
|
|
98
|
+
throw new Error(errorMsg);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = {
|
|
103
|
+
transformJsx: nativeBinding.transformJsx,
|
|
104
|
+
resolveRuntimeStyles: nativeBinding.resolveRuntimeStyles,
|
|
105
|
+
};
|
|
Binary file
|
|
Binary file
|
package/dist/babel.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = _default;
|
|
7
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
|
+
var _babel = require("./utils/babel.js");
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
11
|
+
var libRoot = _path["default"].dirname(__filename);
|
|
12
|
+
|
|
13
|
+
// Cache for loaded stylesheets
|
|
14
|
+
var stylesheetCache = new Map();
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Load pre-computed stylesheet JSON (generated by Metro transformer)
|
|
18
|
+
*/
|
|
19
|
+
function loadStylesheet(cssPath, fileDir) {
|
|
20
|
+
if (stylesheetCache.has(cssPath)) {
|
|
21
|
+
return stylesheetCache.get(cssPath);
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
var cwd = process.cwd();
|
|
25
|
+
var cleanPath = cssPath.replace(/^@\//, "");
|
|
26
|
+
|
|
27
|
+
// 1. Try project root relative paths
|
|
28
|
+
var projectRootJson = _path["default"].resolve(cwd, cleanPath.endsWith(".json") ? cleanPath : "".concat(cleanPath, ".json"));
|
|
29
|
+
if (_fs["default"].existsSync(projectRootJson)) {
|
|
30
|
+
var content = _fs["default"].readFileSync(projectRootJson, "utf-8");
|
|
31
|
+
var stylesheet = JSON.parse(content);
|
|
32
|
+
stylesheetCache.set(cssPath, stylesheet);
|
|
33
|
+
return stylesheet;
|
|
34
|
+
}
|
|
35
|
+
var defaultIndexJson = _path["default"].resolve(cwd, "index.css.json");
|
|
36
|
+
if (_fs["default"].existsSync(defaultIndexJson)) {
|
|
37
|
+
var _content = _fs["default"].readFileSync(defaultIndexJson, "utf-8");
|
|
38
|
+
var _stylesheet = JSON.parse(_content);
|
|
39
|
+
stylesheetCache.set(cssPath, _stylesheet);
|
|
40
|
+
return _stylesheet;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 2. Try fileDir if provided
|
|
44
|
+
if (fileDir) {
|
|
45
|
+
var localJson = _path["default"].resolve(fileDir, cssPath);
|
|
46
|
+
if (_fs["default"].existsSync(localJson)) {
|
|
47
|
+
var _content2 = _fs["default"].readFileSync(localJson, "utf-8");
|
|
48
|
+
var _stylesheet2 = JSON.parse(_content2);
|
|
49
|
+
stylesheetCache.set(cssPath, _stylesheet2);
|
|
50
|
+
return _stylesheet2;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 3. Try resolving the module if it's a module specifier like @colorye/react-native-css/exported-stylesheet.json
|
|
55
|
+
try {
|
|
56
|
+
var resolvedModule = require.resolve(cssPath, {
|
|
57
|
+
paths: [cwd, libRoot]
|
|
58
|
+
});
|
|
59
|
+
if (_fs["default"].existsSync(resolvedModule)) {
|
|
60
|
+
var _content3 = _fs["default"].readFileSync(resolvedModule, "utf-8");
|
|
61
|
+
var _stylesheet3 = JSON.parse(_content3);
|
|
62
|
+
stylesheetCache.set(cssPath, _stylesheet3);
|
|
63
|
+
return _stylesheet3;
|
|
64
|
+
}
|
|
65
|
+
} catch (_unused) {}
|
|
66
|
+
|
|
67
|
+
// 4. Try the exported-stylesheet.json from lib directory
|
|
68
|
+
var exportedPath = _path["default"].join(libRoot, "exported-stylesheet.json");
|
|
69
|
+
if (_fs["default"].existsSync(exportedPath)) {
|
|
70
|
+
var _content4 = _fs["default"].readFileSync(exportedPath, "utf-8");
|
|
71
|
+
var _stylesheet4 = JSON.parse(_content4);
|
|
72
|
+
stylesheetCache.set(cssPath, _stylesheet4);
|
|
73
|
+
return _stylesheet4;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 5. Try .json next to the CSS file
|
|
77
|
+
var cssJsonPath = "".concat(cssPath, ".json");
|
|
78
|
+
if (_fs["default"].existsSync(cssJsonPath)) {
|
|
79
|
+
var _content5 = _fs["default"].readFileSync(cssJsonPath, "utf-8");
|
|
80
|
+
var _stylesheet5 = JSON.parse(_content5);
|
|
81
|
+
stylesheetCache.set(cssPath, _stylesheet5);
|
|
82
|
+
return _stylesheet5;
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
} catch (_unused2) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function _default(_ref) {
|
|
90
|
+
var t = _ref.types;
|
|
91
|
+
return {
|
|
92
|
+
name: "@colorye/react-native-css",
|
|
93
|
+
visitor: {
|
|
94
|
+
Program: {
|
|
95
|
+
enter: function enter(path, state) {
|
|
96
|
+
if (!this.opts.css) {
|
|
97
|
+
console.warn("No css file provided");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
var filename = state.file.opts.filename;
|
|
101
|
+
var options = {
|
|
102
|
+
paths: this.opts.paths || [],
|
|
103
|
+
excludes: this.opts.excludes || [],
|
|
104
|
+
css: this.opts.css
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Normalize filename for cross-platform regex matching
|
|
108
|
+
var normalizedFilename = filename.replace(/\\/g, "/");
|
|
109
|
+
var regex = options.paths.map(function (p) {
|
|
110
|
+
return new RegExp(p);
|
|
111
|
+
});
|
|
112
|
+
var excludesRegex = options.excludes.map(function (p) {
|
|
113
|
+
return new RegExp(p);
|
|
114
|
+
});
|
|
115
|
+
if (!regex.some(function (re) {
|
|
116
|
+
return normalizedFilename.match(re) || filename.match(re);
|
|
117
|
+
}) || excludesRegex.some(function (re) {
|
|
118
|
+
return normalizedFilename.match(re) || filename.match(re);
|
|
119
|
+
})) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
state.enabled = true;
|
|
123
|
+
|
|
124
|
+
// Load pre-computed stylesheet for static inlining
|
|
125
|
+
state.stylesheetData = loadStylesheet(options.css, filename ? _path["default"].dirname(filename) : null);
|
|
126
|
+
|
|
127
|
+
// Track which runtime helpers we need
|
|
128
|
+
state.needsGetStyle = false;
|
|
129
|
+
state.needsGetInheritStyle = false;
|
|
130
|
+
state.needsMergeStyles = false;
|
|
131
|
+
|
|
132
|
+
// Prepare runtime helper declarations
|
|
133
|
+
state.stylesheetId = path.scope.generateUidIdentifier();
|
|
134
|
+
state.stylesheet = t.variableDeclaration("var", [t.variableDeclarator(state.stylesheetId, t.callExpression(t.identifier("require"), [t.stringLiteral(options.css)]))]);
|
|
135
|
+
state.getStyleId = path.scope.generateUidIdentifier();
|
|
136
|
+
state.getStyle = t.variableDeclaration("var", [t.variableDeclarator(state.getStyleId, t.memberExpression(t.memberExpression(t.callExpression(t.identifier("require"), [t.stringLiteral("@colorye/react-native-css/dist/transformer-runtime")]), t.identifier("default")), t.identifier("getStyle")))]);
|
|
137
|
+
state.getInheritStyleId = path.scope.generateUidIdentifier();
|
|
138
|
+
state.getInheritStyle = t.variableDeclaration("var", [t.variableDeclarator(state.getInheritStyleId, t.memberExpression(t.memberExpression(t.callExpression(t.identifier("require"), [t.stringLiteral("@colorye/react-native-css/dist/transformer-runtime")]), t.identifier("default")), t.identifier("getInheritStyle")))]);
|
|
139
|
+
state.mergeStylesId = path.scope.generateUidIdentifier();
|
|
140
|
+
state.mergeStyles = t.variableDeclaration("var", [t.variableDeclarator(state.mergeStylesId, t.memberExpression(t.memberExpression(t.callExpression(t.identifier("require"), [t.stringLiteral("@colorye/react-native-css/dist/transformer-runtime")]), t.identifier("default")), t.identifier("mergeStyles")))]);
|
|
141
|
+
},
|
|
142
|
+
exit: function exit(path, state) {
|
|
143
|
+
if (!state.enabled) return;
|
|
144
|
+
var helpers = [];
|
|
145
|
+
|
|
146
|
+
// Only inject helpers that are actually used
|
|
147
|
+
if (state.needsGetStyle) {
|
|
148
|
+
helpers.push(state.stylesheet);
|
|
149
|
+
helpers.push(state.getStyle);
|
|
150
|
+
}
|
|
151
|
+
if (state.needsGetInheritStyle) {
|
|
152
|
+
helpers.push(state.getInheritStyle);
|
|
153
|
+
}
|
|
154
|
+
if (state.needsMergeStyles) {
|
|
155
|
+
helpers.push(state.mergeStyles);
|
|
156
|
+
}
|
|
157
|
+
if (helpers.length === 0) return;
|
|
158
|
+
var lastImport = path.get("body").filter(function (p) {
|
|
159
|
+
return (0, _babel.isImportOrRequire)(p);
|
|
160
|
+
}).pop();
|
|
161
|
+
helpers.reverse().forEach(function (node) {
|
|
162
|
+
return lastImport ? lastImport.insertAfter(node) : path.unshiftContainer("body", node);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
JSXElement: function JSXElement(path, state) {
|
|
167
|
+
if (!state.enabled) return;
|
|
168
|
+
if ((0, _babel.isFragmentElement)(t, path.node.openingElement.name)) return;
|
|
169
|
+
|
|
170
|
+
// Perform zero-runtime static style inlining for static classes
|
|
171
|
+
(0, _babel.inlineStaticAttributes)(path, state, t);
|
|
172
|
+
var openingElement = path.node.openingElement;
|
|
173
|
+
var isRootLevel = (0, _babel.isRootLevelJSXElement)(path);
|
|
174
|
+
var shouldCombineStyles = openingElement.attributes.some(function (attr) {
|
|
175
|
+
var _attr$name;
|
|
176
|
+
return ((_attr$name = attr.name) === null || _attr$name === void 0 ? void 0 : _attr$name.name) === "__combinedStyles";
|
|
177
|
+
});
|
|
178
|
+
if (shouldCombineStyles) {
|
|
179
|
+
var styleExpressions;
|
|
180
|
+
|
|
181
|
+
// Try static inlining first (if stylesheet loaded and class is static)
|
|
182
|
+
if (state.stylesheetData) {
|
|
183
|
+
var staticInfo = (0, _babel.tryGetStaticStyleInfo)(path, state, t);
|
|
184
|
+
if (staticInfo) {
|
|
185
|
+
// Static class! Use lightweight mergeStyles
|
|
186
|
+
styleExpressions = (0, _babel.getStaticMergeExpression)(path, state, t, staticInfo);
|
|
187
|
+
state.needsMergeStyles = true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (!styleExpressions) {
|
|
191
|
+
// Fall back to full runtime getStyle
|
|
192
|
+
state.needsGetStyle = true;
|
|
193
|
+
styleExpressions = (0, _babel.getStyleExpression)(path, state, t);
|
|
194
|
+
}
|
|
195
|
+
var style = openingElement.attributes.find(function (attr) {
|
|
196
|
+
var _attr$name2;
|
|
197
|
+
return ((_attr$name2 = attr.name) === null || _attr$name2 === void 0 ? void 0 : _attr$name2.name) === "style";
|
|
198
|
+
});
|
|
199
|
+
if (style) {
|
|
200
|
+
style.value = t.jsxExpressionContainer(styleExpressions);
|
|
201
|
+
} else {
|
|
202
|
+
openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier("style"), t.jsxExpressionContainer(styleExpressions)));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{":root":{"--font-sans":"-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\",\n \"Noto Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\",\n \"Segoe UI Symbol\", \"Noto Color Emoji\"","--font-mono":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\",\n \"Courier New\", monospace","--spacing":".25rem","--font-weight-semibold":"600","--font-weight-bold":"700","--tracking-wider":".05em","--default-transition-duration":".15s","--default-transition-timing-function":"cubic-bezier(.4, 0, .2, 1)","--default-font-family":"var(--font-sans)","--default-mono-font-family":"var(--font-mono)","--color-yellow-500":"lab(77.1036% 13.6926 83.561)","--color-green-200":"lab(95.239% -10.8266 9.24107)","--color-green-500":"lab(57.4893% -40.5347 37.516)","--color-orange-500":"lab(66.2947% 49.6344 117.647)","--color-red-500":"lab(45.0394% 75.4726 71.4577)","--color-blue-200":"lab(88.4823% -12.6735 -16.6484)","--color-blue-500":"lab(43.2001% 15.8505 -66.7688)","--color-magenta-500":"lab(34.1384% 59.3948 -45.5364)","--color-black":"lab(0% 0 0)","--color-white":"lab(100% 0 0)","--color-navy-100":"lab(95.2175% -1.96895 -3.05733)","--color-navy-200":"lab(88.3954% -1.94326 -3.07581)","--color-navy-300":"lab(76.7078% -5.64724 -9.13405)","--color-navy-400":"lab(58.179% -8.91814 -15.0204)","--color-navy-500":"lab(39.6076% -11.2321 -20.6616)","--color-navy-600":"lab(20.9196% -10.7469 -25.9701)","--color-navy-700":"lab(3.17211% 1.80869 -28.6588)","--color-primary":"var(--color-blue-500)","--color-success":"var(--color-green-500)","--text-2xs":"10px","--text-2xs--line-height":"12px","--text-xs":"12px","--text-xs--line-height":"16px","--text-sm":"14px","--text-sm--line-height":"20px","--text-md":"18px","--text-md--line-height":"24px","--text-2xl":"32px","--text-2xl--line-height":"36px","--radius-lg":"16px","--radius-xl":"20px","--radius-full":"50%"},"static":{"position":"static"},"container":{"_static":{"width":"100%"},"_dynamic":{"@media (min-width: 580px)":{"_static":{"maxWidth":580},"_dynamic":{}},"@media (min-width: 768px)":{"_static":{"maxWidth":768},"_dynamic":{}},"@media (min-width: 980px)":{"_static":{"maxWidth":980},"_dynamic":{}},"@media (min-width: 1200px)":{"_static":{"maxWidth":1200},"_dynamic":{}}}},"mt-0.5":{"_static":{},"_dynamic":{"marginTop":"calc(var(--spacing) * .5)"}},"mt-1":{"_static":{},"_dynamic":{"marginTop":"var(--spacing)"}},"mt-4":{"_static":{},"_dynamic":{"marginTop":"calc(var(--spacing) * 4)"}},"mb-1":{"_static":{},"_dynamic":{"marginBottom":"var(--spacing)"}},"mb-2":{"_static":{},"_dynamic":{"marginBottom":"calc(var(--spacing) * 2)"}},"mb-3":{"_static":{},"_dynamic":{"marginBottom":"calc(var(--spacing) * 3)"}},"mb-4":{"_static":{},"_dynamic":{"marginBottom":"calc(var(--spacing) * 4)"}},"mb-5":{"_static":{},"_dynamic":{"marginBottom":"calc(var(--spacing) * 5)"}},"h-20":{"_static":{},"_dynamic":{"height":"calc(var(--spacing) * 20)"}},"w-20":{"_static":{},"_dynamic":{"width":"calc(var(--spacing) * 20)"}},"w-[48%]":{"width":"48%"},"flex-1":{"flex":1},"transform":{"_static":{},"_dynamic":{"transform":"var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, )"}},"flex-row":{"flexDirection":"row"},"flex-wrap":{"flexWrap":"wrap"},"items-center":{"alignItems":"center"},"justify-between":{"justifyContent":"space-between"},"justify-center":{"justifyContent":"center"},"gap-1":{"_static":{},"_dynamic":{"gap":"var(--spacing)"}},"gap-2":{"_static":{},"_dynamic":{"gap":"calc(var(--spacing) * 2)"}},"gap-y-2.5":{"_static":{},"_dynamic":{"rowGap":"calc(var(--spacing) * 2.5)"}},"rounded-full":{"_static":{},"_dynamic":{"borderRadius":"var(--radius-full)"}},"rounded-lg":{"_static":{},"_dynamic":{"borderRadius":"var(--radius-lg)"}},"rounded-xl":{"_static":{},"_dynamic":{"borderRadius":"var(--radius-xl)"}},"border":{"_static":{"borderWidth":1},"_dynamic":{"borderStyle":"var(--tw-border-style)"}},"border-s-4":{"_static":{"borderInlineStartWidth":4},"_dynamic":{"borderInlineStartStyle":"var(--tw-border-style)"}},"border-blue-500":{"_static":{},"_dynamic":{"borderColor":"var(--color-blue-500)"}},"border-blue-500/30":{"_static":{},"_dynamic":{"borderColor":"color-mix(in oklab, var(--color-blue-500) 30%, transparent)"}},"border-green-500":{"_static":{},"_dynamic":{"borderColor":"var(--color-green-500)"}},"border-green-500/30":{"_static":{},"_dynamic":{"borderColor":"color-mix(in oklab, var(--color-green-500) 30%, transparent)"}},"border-navy-300":{"_static":{},"_dynamic":{"borderColor":"var(--color-navy-300)"}},"border-navy-500":{"_static":{},"_dynamic":{"borderColor":"var(--color-navy-500)"}},"border-orange-500":{"_static":{},"_dynamic":{"borderColor":"var(--color-orange-500)"}},"border-primary":{"_static":{},"_dynamic":{"borderColor":"var(--color-primary)"}},"bg-blue-500":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-blue-500)"}},"bg-blue-500/10":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-blue-500) 10%, transparent)"}},"bg-blue-500/20":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-blue-500) 20%, transparent)"}},"bg-green-500":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-green-500)"}},"bg-green-500/10":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-green-500) 10%, transparent)"}},"bg-green-500/20":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-green-500) 20%, transparent)"}},"bg-magenta-500":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-magenta-500)"}},"bg-navy-100":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-navy-100)"}},"bg-navy-600":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-navy-600)"}},"bg-navy-700":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-navy-700)"}},"bg-orange-500":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-orange-500)"}},"bg-orange-500/10":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-orange-500) 10%, transparent)"}},"bg-primary":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-primary)"}},"bg-primary/20":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-primary) 20%, transparent)"}},"bg-primary/40":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-primary) 40%, transparent)"}},"bg-primary/60":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-primary) 60%, transparent)"}},"bg-primary/80":{"_static":{},"_dynamic":{"backgroundColor":"color-mix(in oklab, var(--color-primary) 80%, transparent)"}},"bg-red-500":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-red-500)"}},"bg-success":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-success)"}},"bg-transparent":{"backgroundColor":"#0000"},"bg-yellow-500":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-yellow-500)"}},"bg-gradient-to-tr":{"_static":{"--tw-gradient-position":"to top right in oklab"},"_dynamic":{"backgroundImage":"linear-gradient(var(--tw-gradient-stops))"}},"p-1":{"_static":{},"_dynamic":{"paddingTop":"var(--spacing)","paddingRight":"var(--spacing)","paddingBottom":"var(--spacing)","paddingLeft":"var(--spacing)"}},"p-3":{"_static":{},"_dynamic":{"paddingTop":"calc(var(--spacing) * 3)","paddingRight":"calc(var(--spacing) * 3)","paddingBottom":"calc(var(--spacing) * 3)","paddingLeft":"calc(var(--spacing) * 3)"}},"p-3.5":{"_static":{},"_dynamic":{"paddingTop":"calc(var(--spacing) * 3.5)","paddingRight":"calc(var(--spacing) * 3.5)","paddingBottom":"calc(var(--spacing) * 3.5)","paddingLeft":"calc(var(--spacing) * 3.5)"}},"p-4":{"_static":{},"_dynamic":{"paddingTop":"calc(var(--spacing) * 4)","paddingRight":"calc(var(--spacing) * 4)","paddingBottom":"calc(var(--spacing) * 4)","paddingLeft":"calc(var(--spacing) * 4)"}},"p-5":{"_static":{},"_dynamic":{"paddingTop":"calc(var(--spacing) * 5)","paddingRight":"calc(var(--spacing) * 5)","paddingBottom":"calc(var(--spacing) * 5)","paddingLeft":"calc(var(--spacing) * 5)"}},"p-6":{"_static":{},"_dynamic":{"paddingTop":"calc(var(--spacing) * 6)","paddingRight":"calc(var(--spacing) * 6)","paddingBottom":"calc(var(--spacing) * 6)","paddingLeft":"calc(var(--spacing) * 6)"}},"px-3":{"_static":{},"_dynamic":{"paddingHorizontal":"calc(var(--spacing) * 3)"}},"px-3.5":{"_static":{},"_dynamic":{"paddingHorizontal":"calc(var(--spacing) * 3.5)"}},"px-4":{"_static":{},"_dynamic":{"paddingHorizontal":"calc(var(--spacing) * 4)"}},"px-5":{"_static":{},"_dynamic":{"paddingHorizontal":"calc(var(--spacing) * 5)"}},"py-1":{"_static":{},"_dynamic":{"paddingVertical":"var(--spacing)"}},"py-2":{"_static":{},"_dynamic":{"paddingVertical":"calc(var(--spacing) * 2)"}},"py-2.5":{"_static":{},"_dynamic":{"paddingVertical":"calc(var(--spacing) * 2.5)"}},"py-3.5":{"_static":{},"_dynamic":{"paddingVertical":"calc(var(--spacing) * 3.5)"}},"py-4":{"_static":{},"_dynamic":{"paddingVertical":"calc(var(--spacing) * 4)"}},"pr-3":{"_static":{},"_dynamic":{"paddingRight":"calc(var(--spacing) * 3)"}},"pb-20":{"_static":{},"_dynamic":{"paddingBottom":"calc(var(--spacing) * 20)"}},"text-2xl":{"_static":{},"_dynamic":{"fontSize":"var(--text-2xl)","lineHeight":"var(--tw-leading, var(--text-2xl--line-height))"}},"text-2xs":{"_static":{},"_dynamic":{"fontSize":"var(--text-2xs)","lineHeight":"var(--tw-leading, var(--text-2xs--line-height))"}},"text-md":{"_static":{},"_dynamic":{"fontSize":"var(--text-md)","lineHeight":"var(--tw-leading, var(--text-md--line-height))"}},"text-sm":{"_static":{},"_dynamic":{"fontSize":"var(--text-sm)","lineHeight":"var(--tw-leading, var(--text-sm--line-height))"}},"text-xs":{"_static":{},"_dynamic":{"fontSize":"var(--text-xs)","lineHeight":"var(--tw-leading, var(--text-xs--line-height))"}},"font-bold":{"_static":{"--tw-font-weight":"var(--font-weight-bold)"},"_dynamic":{"fontWeight":"var(--font-weight-bold)"}},"font-semibold":{"_static":{"--tw-font-weight":"var(--font-weight-semibold)"},"_dynamic":{"fontWeight":"var(--font-weight-semibold)"}},"tracking-wider":{"_static":{"--tw-tracking":"var(--tracking-wider)"},"_dynamic":{"letterSpacing":"var(--tracking-wider)"}},"text-blue-200":{"_static":{},"_dynamic":{"color":"var(--color-blue-200)"}},"text-green-200":{"_static":{},"_dynamic":{"color":"var(--color-green-200)"}},"text-green-500":{"_static":{},"_dynamic":{"color":"var(--color-green-500)"}},"text-navy-200":{"_static":{},"_dynamic":{"color":"var(--color-navy-200)"}},"text-navy-300":{"_static":{},"_dynamic":{"color":"var(--color-navy-300)"}},"text-navy-600":{"_static":{},"_dynamic":{"color":"var(--color-navy-600)"}},"text-navy-700":{"_static":{},"_dynamic":{"color":"var(--color-navy-700)"}},"text-white":{"_static":{},"_dynamic":{"color":"var(--color-white)"}},"text-yellow-500":{"_static":{},"_dynamic":{"color":"var(--color-yellow-500)"}},"capitalize":{"textTransform":"capitalize"},"uppercase":{"textTransform":"uppercase"},"shadow-base":{"_static":{"--tw-shadow":"0px 0px 4px var(--tw-shadow-color, lab(0% 0 0 / .1))"},"_dynamic":{"boxShadow":"var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)"}},"transition":{"_static":{"transitionProperty":"color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events"},"_dynamic":{"transitionTimingFunction":"var(--tw-ease, var(--default-transition-timing-function))","transitionDuration":"var(--tw-duration, var(--default-transition-duration))"}},"transition-all":{"_static":{"transitionProperty":"all"},"_dynamic":{"transitionTimingFunction":"var(--tw-ease, var(--default-transition-timing-function))","transitionDuration":"var(--tw-duration, var(--default-transition-duration))"}},"group-active:scale-105":{"_static":{"--tw-scale-x":"105%","--tw-scale-y":"105%","--tw-scale-z":"105%"},"_dynamic":{"scale":"var(--tw-scale-x) var(--tw-scale-y)"}},"group-active:bg-yellow-500":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-yellow-500)"}},"group-active:text-black":{"_static":{},"_dynamic":{"color":"var(--color-black)"}},"group-active:text-yellow-500":{"_static":{},"_dynamic":{"color":"var(--color-yellow-500)"}},"active:scale-95":{"_static":{"--tw-scale-x":"95%","--tw-scale-y":"95%","--tw-scale-z":"95%"},"_dynamic":{"scale":"var(--tw-scale-x) var(--tw-scale-y)"}},"scale-95":{"_static":{"--tw-scale-x":"95%","--tw-scale-y":"95%","--tw-scale-z":"95%"},"_dynamic":{"scale":"var(--tw-scale-x) var(--tw-scale-y)"}},"active:border-primary":{"_static":{},"_dynamic":{"borderColor":"var(--color-primary)"}},"active:bg-navy-600":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-navy-600)"}},"active:opacity-75":{"opacity":0.75},"opacity-75":{"opacity":0.75},"active:opacity-80":{"opacity":0.8},"opacity-80":{"opacity":0.8},"disabled:bg-navy-400":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-navy-400)"}},"bg-navy-400":{"_static":{},"_dynamic":{"backgroundColor":"var(--color-navy-400)"}},"disabled:opacity-40":{"opacity":0.4},"opacity-40":{"opacity":0.4}}
|