newcandies 0.1.6 → 0.1.8

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 (2) hide show
  1. package/dist/index.js +83 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ var TEMPLATES = {
35
35
  "mini-app-brief": { categories: [{ value: "forms", label: "forms", variants: [{ value: "lite", label: "lite" }] }] },
36
36
  "default": [{ value: "default", label: "Default (Expo Router + Uniwind)" }]
37
37
  };
38
- var program = new Command().name("newcandies").option("-t, --type <type>").option("--template <name>").option("--category <name>").option("--variant <name>").option("-y, --yes").option("--pm <pm>", "npm|pnpm|yarn|bun").option("--no-install").parse(process.argv);
38
+ var program = new Command().name("newcandies").option("-t, --type <type>").option("--template <name>").option("--category <name>").option("--variant <name>").option("-y, --yes").option("--pm <pm>", "npm|pnpm|yarn|bun").option("--no-install").option("--no-prebuild").parse(process.argv);
39
39
  var opts = program.opts();
40
40
  async function main() {
41
41
  console.clear();
@@ -111,9 +111,15 @@ async function main() {
111
111
  const extraDeps = resolveExtraDeps({ type: project.type, template: project.template, category: project.category, variant: project.variant });
112
112
  if (project.install) {
113
113
  const si = p.spinner();
114
- si.start("Installing dependencies (via Expo)");
114
+ si.start("Installing dependencies");
115
115
  await installDeps(project.pm, dest, extraDeps);
116
116
  si.stop("Installed");
117
+ if (opts.prebuild !== false) {
118
+ const sp = p.spinner();
119
+ sp.start("Generating ios/android (expo prebuild)");
120
+ await execa("npx", ["expo", "prebuild", "--non-interactive"], { cwd: dest, stdio: "inherit" });
121
+ sp.stop("Native projects generated");
122
+ }
117
123
  }
118
124
  p.outro([
119
125
  pc.green("Next steps:"),
@@ -157,6 +163,7 @@ async function writeBaseline({ dest, name, withQuery }) {
157
163
  if (withQuery) {
158
164
  baseDeps["@tanstack/react-query"] = "latest";
159
165
  }
166
+ baseDeps["tailwind-merge"] = "latest";
160
167
  const pkg = {
161
168
  name,
162
169
  version: "0.0.0",
@@ -165,12 +172,14 @@ async function writeBaseline({ dest, name, withQuery }) {
165
172
  scripts: {
166
173
  start: "expo start",
167
174
  android: "expo run:android",
168
- ios: "expo run:ios"
175
+ ios: "expo run:ios",
176
+ prebuild: "expo prebuild"
169
177
  },
170
178
  dependencies: baseDeps,
171
179
  devDependencies: {
172
180
  "@types/react": "~19.1.0",
173
- typescript: "~5.9.2"
181
+ typescript: "~5.9.2",
182
+ "babel-plugin-module-resolver": "latest"
174
183
  }
175
184
  };
176
185
  await fs.writeJSON(path.join(dest, "package.json"), pkg, { spaces: 2 });
@@ -210,7 +219,7 @@ async function writeBaseline({ dest, name, withQuery }) {
210
219
  output: "static",
211
220
  favicon: "./assets/images/favicon.png"
212
221
  },
213
- plugins: ["expo-router"],
222
+ plugins: [["expo-router", { appRoot: "./src/app" }]],
214
223
  experiments: {
215
224
  typedRoutes: true
216
225
  }
@@ -222,6 +231,7 @@ async function writeBaseline({ dest, name, withQuery }) {
222
231
  return {
223
232
  presets: ['babel-preset-expo'],
224
233
  plugins: [
234
+ ['module-resolver', { alias: { '~': './' } }],
225
235
  'react-native-reanimated/plugin'
226
236
  ]
227
237
  };
@@ -240,22 +250,79 @@ module.exports = withUniwindConfig(config, {
240
250
  `;
241
251
  await fs.writeFile(path.join(dest, "metro.config.js"), metro);
242
252
  const tsconfig = {
253
+ extends: "expo/tsconfig.base",
243
254
  compilerOptions: {
244
255
  strict: true,
245
- jsx: "react-native",
246
- target: "ES2020",
247
- moduleResolution: "node",
248
- types: ["react", "react-native"]
256
+ paths: {
257
+ "~/*": ["./*"]
258
+ }
249
259
  },
250
- include: ["app", "./uniwind-types.d.ts", "./expo-env.d.ts"]
260
+ include: [
261
+ "**/*.ts",
262
+ "**/*.tsx",
263
+ ".expo/types/**/*.ts",
264
+ "expo-env.d.ts",
265
+ "./uniwind-types.d.ts"
266
+ ]
251
267
  };
252
268
  await fs.writeJSON(path.join(dest, "tsconfig.json"), tsconfig, { spaces: 2 });
253
269
  const expoEnv = `/// <reference types="expo" />
254
270
  /// <reference types="expo-router" />
255
271
  `;
256
272
  await fs.writeFile(path.join(dest, "expo-env.d.ts"), expoEnv);
257
- const appDir = path.join(dest, "app");
273
+ const srcDir = path.join(dest, "src");
274
+ const appDir = path.join(srcDir, "app");
258
275
  await fs.ensureDir(appDir);
276
+ await fs.ensureDir(path.join(srcDir, "core"));
277
+ await fs.ensureDir(path.join(srcDir, "api"));
278
+ await fs.ensureDir(path.join(srcDir, "lib"));
279
+ await fs.ensureDir(path.join(srcDir, "types"));
280
+ await fs.ensureDir(path.join(srcDir, "components", "screens", "home"));
281
+ await fs.ensureDir(path.join(srcDir, "components", "screens", "profile"));
282
+ await fs.ensureDir(path.join(srcDir, "components", "core"));
283
+ const textCore = `import { Text as RNText, TextProps } from 'react-native';
284
+ import { twMerge } from 'tailwind-merge';
285
+
286
+ type TypographyVariant =
287
+ | 'title'
288
+ | 'subtitle'
289
+ | 'body'
290
+ | 'caption'
291
+ | 'button'
292
+ | 'display'
293
+ | 'caption-primary'
294
+ | 'body-primary'
295
+ | 'subtitle-primary';
296
+
297
+ interface TextComponentProps extends TextProps {
298
+ className?: string;
299
+ variant?: TypographyVariant;
300
+ }
301
+
302
+ const variantStyles: Record<TypographyVariant, string> = {
303
+ title: 'text-2xl font-bold',
304
+ subtitle: 'text-xl font-semibold',
305
+ 'subtitle-primary': 'text-xl font-semibold text-primary',
306
+ body: 'text-base',
307
+ 'body-primary': 'text-base text-primary',
308
+ caption: 'text-sm font-medium',
309
+ 'caption-primary': 'text-sm text-primary font-medium',
310
+ button: 'text-xl text-primary font-semibold text-white text-center',
311
+ display: 'text-3x font-bold',
312
+ };
313
+
314
+ const Text = ({ variant = 'body', children, className, ...props }: TextComponentProps) => {
315
+ const textStyle = twMerge('text-black', variantStyles[variant], className);
316
+ return (
317
+ <RNText className={textStyle} {...props}>
318
+ {children}
319
+ </RNText>
320
+ );
321
+ };
322
+
323
+ export default Text;
324
+ `;
325
+ await fs.writeFile(path.join(srcDir, "components", "core", "text.tsx"), textCore);
259
326
  const easJson = {
260
327
  cli: { version: ">= 7.0.0" },
261
328
  build: {
@@ -292,7 +359,7 @@ import { Stack } from "expo-router";
292
359
  import * as SplashScreen from "expo-splash-screen";
293
360
  import { useEffect } from "react";
294
361
  import "react-native-reanimated";
295
- import "../global.css";
362
+ import "../../global.css";
296
363
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
297
364
 
298
365
  export { ErrorBoundary } from "expo-router";
@@ -307,7 +374,7 @@ const queryClient = new QueryClient();
307
374
 
308
375
  export default function RootLayout() {
309
376
  const [loaded, error] = useFonts({
310
- SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
377
+ SpaceMono: require("../../assets/fonts/SpaceMono-Regular.ttf"),
311
378
  ...FontAwesome.font,
312
379
  });
313
380
 
@@ -346,7 +413,7 @@ import { Stack } from "expo-router";
346
413
  import * as SplashScreen from "expo-splash-screen";
347
414
  import { useEffect } from "react";
348
415
  import "react-native-reanimated";
349
- import "../global.css";
416
+ import "../../global.css";
350
417
 
351
418
  export { ErrorBoundary } from "expo-router";
352
419
 
@@ -358,7 +425,7 @@ SplashScreen.preventAutoHideAsync();
358
425
 
359
426
  export default function RootLayout() {
360
427
  const [loaded, error] = useFonts({
361
- SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
428
+ SpaceMono: require("../../assets/fonts/SpaceMono-Regular.ttf"),
362
429
  ...FontAwesome.font,
363
430
  });
364
431
 
@@ -395,6 +462,7 @@ function RootLayoutNav() {
395
462
  import FontAwesome from '@expo/vector-icons/FontAwesome';
396
463
  import { Link, Tabs } from 'expo-router';
397
464
  import { Pressable } from 'react-native';
465
+ import '../../global.css';
398
466
 
399
467
  function TabBarIcon(props: { name: React.ComponentProps<typeof FontAwesome>['name']; color: string; }) {
400
468
  return <FontAwesome size={28} style={{ marginBottom: -3 }} {...props} />;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newcandies",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Scaffold Expo Router + Uniwind React Native apps with layered templates.",
5
5
  "type": "module",
6
6
  "bin": {