zelune 1.5.6 → 1.5.7
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/runtime/MockNavigationContext.tsx +48 -1
- package/src/runtime/nativewindShim.ts +25 -0
- package/vite.config.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the **Zelune — React Native Visual Canvas & MCP** project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.5.7] - 2026-10-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Universal NativeWind v2/v4 (`styled`, `cssInterop`, `remapProps`), `twrnc` (`tw`, `createTw`), & TypeScript `tailwind.config.ts` Support (`src/runtime/nativewindShim.ts`, `src/runtime/MockNavigationContext.tsx`, `vite.config.ts`)**:
|
|
9
|
+
- Added `styled(Component, baseClassName)` (NativeWind v2), `cssInterop` / `remapProps` (NativeWind v4), and `tw` / `createTw` (`twrnc` tagged templates and `.style()` helper) to `MockNavigationContext.tsx` so any React Native project worldwide using NativeWind v2, NativeWind v4, or `twrnc` works out-of-the-box.
|
|
10
|
+
- Added dynamic `fontFamily` token resolution from `window.__ZELUNE_TAILWIND_THEME__.fontFamily` in `src/runtime/nativewindShim.ts` and TypeScript type-stripping (`const config: Config =`, `satisfies Config`, `as const`) in `loadProjectTailwindTheme` (`vite.config.ts`).
|
|
11
|
+
|
|
5
12
|
## [1.5.6] - 2026-10-24
|
|
6
13
|
|
|
7
14
|
### Added
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
ScrollView as RNScrollView,
|
|
12
12
|
FlatList as RNFlatList,
|
|
13
13
|
} from 'react-native';
|
|
14
|
-
import { withNativeWind } from './nativewindShim';
|
|
14
|
+
import { withNativeWind, resolveTailwindClassNameToStyle } from './nativewindShim';
|
|
15
15
|
|
|
16
16
|
export interface NavigationController {
|
|
17
17
|
navigate: (targetRoute: string, params?: Record<string, unknown>) => void;
|
|
@@ -1221,6 +1221,53 @@ export const clsx = (...args: unknown[]) =>
|
|
|
1221
1221
|
export const cn = clsx;
|
|
1222
1222
|
export const twMerge = clsx;
|
|
1223
1223
|
|
|
1224
|
+
// NativeWind (v2 / v4) & twrnc Universal Shims
|
|
1225
|
+
export function styled<P extends Record<string, unknown>>(
|
|
1226
|
+
Component: React.ComponentType<P>,
|
|
1227
|
+
baseClassName?: string
|
|
1228
|
+
): React.ComponentType<P> {
|
|
1229
|
+
const Wrapped = withNativeWind(Component as unknown as React.ComponentType<Record<string, unknown>>);
|
|
1230
|
+
if (!baseClassName) return Wrapped as unknown as React.ComponentType<P>;
|
|
1231
|
+
return React.forwardRef<unknown, P>((props, ref) => {
|
|
1232
|
+
const combinedClass = [baseClassName, props?.className].filter(Boolean).join(' ');
|
|
1233
|
+
return React.createElement(Wrapped, { ...props, className: combinedClass, ref });
|
|
1234
|
+
}) as unknown as React.ComponentType<P>;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
export function cssInterop<P extends Record<string, unknown>>(
|
|
1238
|
+
Component: React.ComponentType<P>
|
|
1239
|
+
): React.ComponentType<P> {
|
|
1240
|
+
return withNativeWind(Component as unknown as React.ComponentType<Record<string, unknown>>) as unknown as React.ComponentType<P>;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
export const remapProps = cssInterop;
|
|
1244
|
+
|
|
1245
|
+
function twFn(stringsOrClass: TemplateStringsArray | string, ...values: unknown[]): Record<string, unknown> {
|
|
1246
|
+
if (typeof stringsOrClass === 'string') {
|
|
1247
|
+
return resolveTailwindClassNameToStyle(stringsOrClass) ?? {};
|
|
1248
|
+
}
|
|
1249
|
+
if (Array.isArray(stringsOrClass)) {
|
|
1250
|
+
const built = stringsOrClass.reduce(
|
|
1251
|
+
(acc, str, idx) => acc + str + (values[idx] !== undefined ? String(values[idx]) : ''),
|
|
1252
|
+
''
|
|
1253
|
+
);
|
|
1254
|
+
return resolveTailwindClassNameToStyle(built) ?? {};
|
|
1255
|
+
}
|
|
1256
|
+
return {};
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
twFn.style = (...args: unknown[]) => {
|
|
1260
|
+
const mergedClass = args.filter((a): a is string => typeof a === 'string' && a.length > 0).join(' ');
|
|
1261
|
+
return resolveTailwindClassNameToStyle(mergedClass) ?? {};
|
|
1262
|
+
};
|
|
1263
|
+
twFn.color = (token: string) => {
|
|
1264
|
+
const s = resolveTailwindClassNameToStyle(`text-${token}`);
|
|
1265
|
+
return (s?.color as string | undefined) ?? '#0F172A';
|
|
1266
|
+
};
|
|
1267
|
+
|
|
1268
|
+
export const tw = twFn;
|
|
1269
|
+
export const createTw = () => twFn;
|
|
1270
|
+
|
|
1224
1271
|
// React Hook Form Shims (react-hook-form)
|
|
1225
1272
|
export function useForm(config?: { defaultValues?: Record<string, unknown> }) {
|
|
1226
1273
|
const defaults = config?.defaultValues ?? {};
|
|
@@ -376,6 +376,7 @@ export function resolveTailwindClassNameToStyle(className?: string): Record<stri
|
|
|
376
376
|
(typeof window !== 'undefined' && window.__ZELUNE_TAILWIND_THEME__) || {};
|
|
377
377
|
const themeColors = (projectTheme.colors ?? {}) as Record<string, unknown>;
|
|
378
378
|
const themeFontSizes = (projectTheme.fontSize ?? {}) as Record<string, unknown>;
|
|
379
|
+
const themeFontFamilies = (projectTheme.fontFamily ?? {}) as Record<string, unknown>;
|
|
379
380
|
const themeRadii = (projectTheme.borderRadius ?? {}) as Record<string, unknown>;
|
|
380
381
|
const themeSpacing = (projectTheme.spacing ?? {}) as Record<string, unknown>;
|
|
381
382
|
|
|
@@ -808,6 +809,30 @@ export function resolveTailwindClassNameToStyle(className?: string): Record<stri
|
|
|
808
809
|
style.fontFamily = 'monospace';
|
|
809
810
|
continue;
|
|
810
811
|
}
|
|
812
|
+
if (token.startsWith('font-')) {
|
|
813
|
+
const fontKey = token.slice(5);
|
|
814
|
+
const customFontEntry = themeFontFamilies[fontKey];
|
|
815
|
+
if (customFontEntry !== undefined) {
|
|
816
|
+
const primaryFont = Array.isArray(customFontEntry)
|
|
817
|
+
? String(customFontEntry[0] ?? '')
|
|
818
|
+
: String(customFontEntry ?? '');
|
|
819
|
+
const lowerFont = primaryFont.toLowerCase();
|
|
820
|
+
if (lowerFont.includes('800') || lowerFont.includes('extrabold') || lowerFont.includes('black')) {
|
|
821
|
+
style.fontWeight = '800';
|
|
822
|
+
} else if (lowerFont.includes('700') || lowerFont.includes('bold')) {
|
|
823
|
+
style.fontWeight = lowerFont.includes('semibold') ? '600' : '700';
|
|
824
|
+
} else if (lowerFont.includes('600') || lowerFont.includes('semibold')) {
|
|
825
|
+
style.fontWeight = '600';
|
|
826
|
+
} else if (lowerFont.includes('500') || lowerFont.includes('medium')) {
|
|
827
|
+
style.fontWeight = '500';
|
|
828
|
+
} else if (lowerFont.includes('300') || lowerFont.includes('light')) {
|
|
829
|
+
style.fontWeight = '300';
|
|
830
|
+
} else {
|
|
831
|
+
style.fontWeight = '400';
|
|
832
|
+
}
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
811
836
|
|
|
812
837
|
// Letter spacing (tracking-*)
|
|
813
838
|
if (token === 'tracking-tighter') {
|
package/vite.config.ts
CHANGED
|
@@ -112,6 +112,9 @@ function loadProjectTailwindTheme(roots: string[]): Record<string, unknown> {
|
|
|
112
112
|
const raw = fs.readFileSync(fullPath, 'utf-8');
|
|
113
113
|
const cleaned = raw
|
|
114
114
|
.replace(/^import\s+.*$/gm, '')
|
|
115
|
+
.replace(/\b(const|let|var)\s+([A-Za-z0-9_$]+)\s*:\s*[^=]+=/g, '$1 $2 =')
|
|
116
|
+
.replace(/\bsatisfies\s+[A-Za-z0-9_$.<>]+/g, '')
|
|
117
|
+
.replace(/\bas\s+const\b/g, '')
|
|
115
118
|
.replace(/export\s+default\s+/, 'module.exports = ');
|
|
116
119
|
const mod = { exports: {} as Record<string, unknown> };
|
|
117
120
|
const fakeRequire = () => ({});
|