react-native-twc 1.1.1 → 1.1.3

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.
Files changed (4) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +9 -13
  3. package/dist/index.js +64 -74
  4. package/package.json +66 -75
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023-Present Greg Bergé
3
+ Copyright (c) 2026 Ldy
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Create reusable React Native + NativeWind components with Tailwind CSS syntax
4
4
 
5
- This project is a **React Native adaptation** of [TWC (react-twc)](https://github.com/gregberge/twc) by [Greg Bergé](https://github.com/gregberge). The original TWC library provides an elegant way to create styled React components with Tailwind CSS. This fork adapts the library specifically for React Native with NativeWind support.
5
+ A lightweight library for creating styled React Native components using Tailwind CSS class syntax with NativeWind support. Inspired by [TWC (react-twc)](https://github.com/gregberge/twc).
6
6
 
7
7
  ## Features
8
8
 
@@ -258,10 +258,10 @@ import { twx } from "react-native-twc";
258
258
  const Title = twx(Text)`font-bold`;
259
259
  ```
260
260
 
261
- ## Differences from Original TWC
261
+ ## Differences from TWC (Web)
262
262
 
263
- | Feature | Original TWC | react-native-twc |
264
- |---------|--------------|------------------|
263
+ | Feature | TWC (Web) | react-native-twc |
264
+ |---------|-----------|------------------|
265
265
  | HTML tags (`twc.div`) | ✅ Supported | ❌ Not supported |
266
266
  | `asChild` prop | ✅ Supported | ❌ Not supported |
267
267
  | React Native components | ❌ Not optimized | ✅ Fully supported |
@@ -269,15 +269,11 @@ const Title = twx(Text)`font-bold`;
269
269
 
270
270
  ## Acknowledgements
271
271
 
272
- - [TWC (react-twc)](https://github.com/gregberge/twc) by [Greg Bergé](https://github.com/gregberge) - The original inspiration and foundation for this project
273
- - [NativeWind](https://www.nativewind.dev/) - Tailwind CSS for React Native
274
- - [styled-components](https://styled-components.com) - Where the template literal API originated
275
- - [tailwind-merge](https://github.com/dcastil/tailwind-merge) - Intelligent Tailwind class merging
272
+ - [TWC (react-twc)](https://github.com/gregberge/twc) by [Greg Bergé](https://github.com/gregberge) The original inspiration for this project
273
+ - [NativeWind](https://www.nativewind.dev/) Tailwind CSS for React Native
274
+ - [styled-components](https://styled-components.com) Where the template literal API originated
275
+ - [tailwind-merge](https://github.com/dcastil/tailwind-merge) Intelligent Tailwind class merging
276
276
 
277
277
  ## License
278
278
 
279
- MIT License © 2023-Present [Greg Bergé](https://github.com/gregberge)
280
-
281
- ---
282
-
283
- **Note:** This is a community fork adapted for React Native. For the original React (web) version, please visit [react-twc](https://github.com/gregberge/twc).
279
+ MIT
package/dist/index.js CHANGED
@@ -1,81 +1,71 @@
1
- // src/index.tsx
2
1
  import { clsx } from "clsx";
3
2
  import React from "react";
4
3
  import { twMerge } from "tailwind-merge";
5
4
  import { jsx } from "react/jsx-runtime";
5
+
6
6
  function filterProps(props, shouldForwardProp) {
7
- const filteredProps = {};
8
- const keys = Object.keys(props);
9
- for (let i = 0;i < keys.length; i++) {
10
- const prop = keys[i];
11
- if (shouldForwardProp(prop)) {
12
- filteredProps[prop] = props[prop];
13
- }
14
- }
15
- return filteredProps;
7
+ const filteredProps = {};
8
+ const keys = Object.keys(props);
9
+ for (let i = 0; i < keys.length; i++) {
10
+ const prop = keys[i];
11
+ if (shouldForwardProp(prop)) filteredProps[prop] = props[prop];
12
+ }
13
+ return filteredProps;
16
14
  }
17
- var createTwc = (config = {}) => {
18
- const compose = config.compose || clsx;
19
- const defaultShouldForwardProp = config.shouldForwardProp || ((prop) => prop[0] !== "$");
20
- const wrap = (Component) => {
21
- const createTemplate = (attrs, shouldForwardProp = defaultShouldForwardProp) => {
22
- const componentCache = new Map;
23
- const template = (stringsOrFn, ...values) => {
24
- const isClassFn = typeof stringsOrFn === "function";
25
- const cacheKey = isClassFn ? stringsOrFn.toString() : String.raw({ raw: stringsOrFn }, ...values);
26
- if (componentCache.has(cacheKey)) {
27
- return componentCache.get(cacheKey);
28
- }
29
- const tplClassName = !isClassFn ? cacheKey : undefined;
30
- const hasAttrs = attrs !== undefined;
31
- const isAttrsFunction = typeof attrs === "function";
32
- const staticAttrs = !isAttrsFunction && hasAttrs ? attrs : undefined;
33
- const ForwardedComponent = React.forwardRef((p, ref) => {
34
- const { className: classNameProp, ...rest } = p;
35
- let finalProps;
36
- if (!hasAttrs) {
37
- finalProps = filterProps(rest, shouldForwardProp);
38
- } else if (isAttrsFunction) {
39
- const resolvedAttrs = attrs(p);
40
- finalProps = filterProps({ ...resolvedAttrs, ...rest }, shouldForwardProp);
41
- } else {
42
- finalProps = filterProps({ ...staticAttrs, ...rest }, shouldForwardProp);
43
- }
44
- const baseClassName = isClassFn ? stringsOrFn(p) : tplClassName;
45
- const finalClassName = typeof baseClassName === "function" ? (renderProps) => compose(baseClassName(renderProps), typeof classNameProp === "function" ? classNameProp(renderProps) : classNameProp) : compose(baseClassName, classNameProp);
46
- const Comp = Component;
47
- return /* @__PURE__ */ jsx(Comp, {
48
- ref,
49
- className: finalClassName,
50
- ...finalProps
51
- });
52
- });
53
- ForwardedComponent.displayName = `twc(${Component.displayName || Component.name || "Component"})`;
54
- componentCache.set(cacheKey, ForwardedComponent);
55
- return ForwardedComponent;
56
- };
57
- template.transientProps = (fnOrArray) => {
58
- const shouldForwardProp2 = typeof fnOrArray === "function" ? (prop) => !fnOrArray(prop) : (prop) => !fnOrArray.includes(prop);
59
- return createTemplate(attrs, shouldForwardProp2);
60
- };
61
- if (attrs === undefined) {
62
- template.attrs = (attrs2) => {
63
- return createTemplate(attrs2, shouldForwardProp);
64
- };
65
- }
66
- return template;
67
- };
68
- return createTemplate();
69
- };
70
- return wrap;
71
- };
72
- var twc = createTwc();
73
- var cn = (...inputs) => twMerge(clsx(inputs));
74
- var twx = createTwc({ compose: cn });
75
- export {
76
- twx,
77
- twc,
78
- clsx as cx,
79
- createTwc,
80
- cn
15
+
16
+ const createTwc = (config = {}) => {
17
+ const compose = config.compose || clsx;
18
+ const defaultShouldForwardProp = config.shouldForwardProp || ((prop) => prop[0] !== "$");
19
+ const wrap = (Component) => {
20
+ const createTemplate = (attrs, shouldForwardProp = defaultShouldForwardProp) => {
21
+ const componentCache = /* @__PURE__ */ new Map();
22
+ const template = (stringsOrFn, ...values) => {
23
+ const isClassFn = typeof stringsOrFn === "function";
24
+ const cacheKey = isClassFn ? stringsOrFn.toString() : String.raw({ raw: stringsOrFn }, ...values);
25
+ if (componentCache.has(cacheKey)) return componentCache.get(cacheKey);
26
+ const tplClassName = !isClassFn ? cacheKey : void 0;
27
+ const hasAttrs = attrs !== void 0;
28
+ const isAttrsFunction = typeof attrs === "function";
29
+ const staticAttrs = !isAttrsFunction && hasAttrs ? attrs : void 0;
30
+ const ForwardedComponent = React.forwardRef((p, ref) => {
31
+ const { className: classNameProp, ...rest } = p;
32
+ let finalProps;
33
+ if (!hasAttrs) finalProps = filterProps(rest, shouldForwardProp);
34
+ else if (isAttrsFunction) finalProps = filterProps({
35
+ ...attrs(p),
36
+ ...rest
37
+ }, shouldForwardProp);
38
+ else finalProps = filterProps({
39
+ ...staticAttrs,
40
+ ...rest
41
+ }, shouldForwardProp);
42
+ const baseClassName = isClassFn ? stringsOrFn(p) : tplClassName;
43
+ return /* @__PURE__ */ jsx(Component, {
44
+ ref,
45
+ className: typeof baseClassName === "function" ? (renderProps) => compose(baseClassName(renderProps), typeof classNameProp === "function" ? classNameProp(renderProps) : classNameProp) : compose(baseClassName, classNameProp),
46
+ ...finalProps
47
+ });
48
+ });
49
+ ForwardedComponent.displayName = `twc(${Component.displayName || Component.name || "Component"})`;
50
+ componentCache.set(cacheKey, ForwardedComponent);
51
+ return ForwardedComponent;
52
+ };
53
+ template.transientProps = (fnOrArray) => {
54
+ return createTemplate(attrs, typeof fnOrArray === "function" ? (prop) => !fnOrArray(prop) : (prop) => !fnOrArray.includes(prop));
55
+ };
56
+ if (attrs === void 0) template.attrs = (attrs$1) => {
57
+ return createTemplate(attrs$1, shouldForwardProp);
58
+ };
59
+ return template;
60
+ };
61
+ return createTemplate();
62
+ };
63
+ return wrap;
81
64
  };
65
+
66
+ const twc = createTwc();
67
+ const cn = (...inputs) => twMerge(clsx(inputs));
68
+
69
+ const twx = createTwc({ compose: cn });
70
+
71
+ export { cn, createTwc, clsx as cx, twc, twx };
package/package.json CHANGED
@@ -1,79 +1,70 @@
1
1
  {
2
- "name": "react-native-twc",
3
- "version": "1.1.1",
4
- "description": "Create reusable React Native + NativeWind components with Tailwind CSS syntax.",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./dist/index.d.ts",
12
- "import": "./dist/index.js",
13
- "require": "./dist/index.js",
14
- "default": "./dist/index.js"
15
- }
16
- },
17
- "scripts": {
18
- "test": "bun test",
19
- "build": "rm -rf dist && bun run build:js && bun run build:dts",
20
- "build:js": "NODE_ENV=production bun build src/index.tsx --outdir dist --format esm --external react --external react-native --external clsx --external tailwind-merge",
21
- "build:dts": "tsc -p tsconfig.build.json",
22
- "check-types": "tsc --noEmit",
23
- "prepublishOnly": "bun run build && bun test"
24
- },
25
- "keywords": [
26
- "react-native",
27
- "nativewind",
28
- "tailwind",
29
- "css",
30
- "components",
31
- "styled",
32
- "styled-components",
33
- "expo"
34
- ],
35
- "author": "ldystudio",
36
- "license": "MIT",
37
- "repository": {
38
- "type": "git",
39
- "url": "git+https://github.com/ldystudio/react-native-twc.git"
40
- },
41
- "homepage": "https://react-twc.vercel.app",
42
- "devDependencies": {
43
- "@eslint/eslintrc": "^3.3.1",
44
- "@eslint/js": "^9.30.0",
45
- "@happy-dom/global-registrator": "^18.0.1",
46
- "@testing-library/react": "^16.3.0",
47
- "@types/bun": "^1.2.5",
48
- "@types/react": "^19.1.8",
49
- "@typescript-eslint/eslint-plugin": "^8.35.0",
50
- "@typescript-eslint/parser": "^8.35.0",
51
- "class-variance-authority": "^0.7.1",
52
- "eslint": "^9.30.0",
53
- "happy-dom": "^18.0.1",
54
- "prettier": "^3.6.2",
55
- "react": "^19.1.0",
56
- "react-dom": "^19.1.0",
57
- "tailwind-merge": "^3.3.1",
58
- "typescript": "^5.8.3",
59
- "typescript-eslint": "^8.35.0",
60
- "ultracite": "7.0.10"
61
- },
62
- "dependencies": {
63
- "clsx": "^2.1.1"
64
- },
65
- "peerDependencies": {
66
- "react": ">=18.0.0",
67
- "react-native": ">=0.72.0",
68
- "nativewind": ">=4.0.0",
69
- "tailwind-merge": ">=3.3.1"
2
+ "name": "react-native-twc",
3
+ "version": "1.1.3",
4
+ "description": "Create reusable React Native + NativeWind components with Tailwind CSS syntax.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "test": "bun test",
17
+ "build": "rm -rf dist && rolldown -c && tsc -p tsconfig.build.json",
18
+ "check-types": "tsc --noEmit",
19
+ "prepublishOnly": "bun test && bun run build"
20
+ },
21
+ "keywords": [
22
+ "react-native",
23
+ "nativewind",
24
+ "tailwind",
25
+ "css",
26
+ "components",
27
+ "styled",
28
+ "styled-components",
29
+ "expo"
30
+ ],
31
+ "author": "ldystudio",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/ldystudio/react-native-twc.git"
36
+ },
37
+ "homepage": "https://react-twc.vercel.app",
38
+ "devDependencies": {
39
+ "@biomejs/biome": "^2.3.11",
40
+ "@happy-dom/global-registrator": "^18.0.1",
41
+ "@testing-library/react": "^16.3.0",
42
+ "@types/bun": "^1.2.5",
43
+ "@types/react": "^19.1.8",
44
+ "class-variance-authority": "^0.7.1",
45
+ "happy-dom": "^18.0.1",
46
+ "prettier": "^3.6.2",
47
+ "react": "^19.1.0",
48
+ "react-dom": "^19.1.0",
49
+ "rolldown": "^1.0.0-beta.59",
50
+ "tailwind-merge": "^3.3.1",
51
+ "typescript": "^5.8.3"
52
+ },
53
+ "dependencies": {
54
+ "clsx": "^2.1.1"
55
+ },
56
+ "peerDependencies": {
57
+ "react": ">=18.0.0",
58
+ "react-native": ">=0.72.0",
59
+ "nativewind": ">=4.0.0",
60
+ "tailwind-merge": ">=3.3.1"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "react-native": {
64
+ "optional": true
70
65
  },
71
- "peerDependenciesMeta": {
72
- "react-native": {
73
- "optional": true
74
- },
75
- "nativewind": {
76
- "optional": true
77
- }
66
+ "nativewind": {
67
+ "optional": true
78
68
  }
69
+ }
79
70
  }