getlotui 0.1.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.
Files changed (128) hide show
  1. package/README.md +78 -0
  2. package/dist/bin.d.ts +2 -0
  3. package/dist/bin.js +5 -0
  4. package/dist/commands/add.d.ts +1 -0
  5. package/dist/commands/add.js +37 -0
  6. package/dist/commands/init.d.ts +1 -0
  7. package/dist/commands/init.js +93 -0
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +22 -0
  10. package/dist/templates/expo/Accordion.d.ts +14 -0
  11. package/dist/templates/expo/Accordion.js +118 -0
  12. package/dist/templates/expo/Accordion.tsx +152 -0
  13. package/dist/templates/expo/AlertDialog.d.ts +12 -0
  14. package/dist/templates/expo/AlertDialog.js +126 -0
  15. package/dist/templates/expo/AlertDialog.tsx +147 -0
  16. package/dist/templates/expo/Avatar.d.ts +8 -0
  17. package/dist/templates/expo/Avatar.js +81 -0
  18. package/dist/templates/expo/Avatar.tsx +78 -0
  19. package/dist/templates/expo/Badge.d.ts +6 -0
  20. package/dist/templates/expo/Badge.js +60 -0
  21. package/dist/templates/expo/Badge.tsx +67 -0
  22. package/dist/templates/expo/Button.d.ts +9 -0
  23. package/dist/templates/expo/Button.js +37 -0
  24. package/dist/templates/expo/Button.tsx +53 -0
  25. package/dist/templates/expo/Dropdown.d.ts +12 -0
  26. package/dist/templates/expo/Dropdown.js +91 -0
  27. package/dist/templates/expo/Dropdown.tsx +100 -0
  28. package/dist/templates/expo/Input.d.ts +11 -0
  29. package/dist/templates/expo/Input.js +43 -0
  30. package/dist/templates/expo/Input.tsx +67 -0
  31. package/dist/templates/expo/Toast.d.ts +16 -0
  32. package/dist/templates/expo/Toast.js +142 -0
  33. package/dist/templates/expo/Toast.tsx +161 -0
  34. package/dist/templates/expo/utils.d.ts +4 -0
  35. package/dist/templates/expo/utils.js +10 -0
  36. package/dist/templates/expo/utils.ts +8 -0
  37. package/dist/templates/flutter/Accordion.dart +142 -0
  38. package/dist/templates/flutter/Alert.dart +96 -0
  39. package/dist/templates/flutter/AlertDialog.dart +175 -0
  40. package/dist/templates/flutter/Avatar.dart +82 -0
  41. package/dist/templates/flutter/Badge.dart +89 -0
  42. package/dist/templates/flutter/Button.dart +116 -0
  43. package/dist/templates/flutter/Card.dart +91 -0
  44. package/dist/templates/flutter/Input.dart +73 -0
  45. package/dist/templates/flutter/Text.dart +87 -0
  46. package/dist/templates/flutter/utils.dart +13 -0
  47. package/dist/templates/templates/expo/Button.tsx +50 -0
  48. package/dist/templates/templates/expo/Input.tsx +67 -0
  49. package/dist/templates/web/Accordion.d.ts +7 -0
  50. package/dist/templates/web/Accordion.js +59 -0
  51. package/dist/templates/web/Accordion.tsx +64 -0
  52. package/dist/templates/web/Alert.d.ts +9 -0
  53. package/dist/templates/web/Alert.js +64 -0
  54. package/dist/templates/web/Alert.tsx +71 -0
  55. package/dist/templates/web/AlertDialog.d.ts +14 -0
  56. package/dist/templates/web/AlertDialog.js +85 -0
  57. package/dist/templates/web/AlertDialog.tsx +164 -0
  58. package/dist/templates/web/Avatar.d.ts +6 -0
  59. package/dist/templates/web/Avatar.js +50 -0
  60. package/dist/templates/web/Avatar.tsx +51 -0
  61. package/dist/templates/web/Badge.d.ts +9 -0
  62. package/dist/templates/web/Badge.js +59 -0
  63. package/dist/templates/web/Badge.tsx +38 -0
  64. package/dist/templates/web/Button.d.ts +10 -0
  65. package/dist/templates/web/Button.js +70 -0
  66. package/dist/templates/web/Button.tsx +60 -0
  67. package/dist/templates/web/Card.d.ts +9 -0
  68. package/dist/templates/web/Card.js +65 -0
  69. package/dist/templates/web/Card.tsx +92 -0
  70. package/dist/templates/web/Dropdown.d.ts +27 -0
  71. package/dist/templates/web/Dropdown.js +95 -0
  72. package/dist/templates/web/Dropdown.tsx +198 -0
  73. package/dist/templates/web/Input.d.ts +3 -0
  74. package/dist/templates/web/Input.js +41 -0
  75. package/dist/templates/web/Input.tsx +21 -0
  76. package/dist/templates/web/Tabs.d.ts +7 -0
  77. package/dist/templates/web/Tabs.js +55 -0
  78. package/dist/templates/web/Tabs.tsx +66 -0
  79. package/dist/templates/web/Toast.d.ts +15 -0
  80. package/dist/templates/web/Toast.js +75 -0
  81. package/dist/templates/web/Toast.tsx +126 -0
  82. package/dist/templates/web/utils.d.ts +2 -0
  83. package/dist/templates/web/utils.js +8 -0
  84. package/dist/templates/web/utils.ts +6 -0
  85. package/dist/utils/detect.d.ts +19 -0
  86. package/dist/utils/detect.js +90 -0
  87. package/dist/utils/fs.d.ts +5 -0
  88. package/dist/utils/fs.js +35 -0
  89. package/getlotui.config.json +4 -0
  90. package/package.json +31 -0
  91. package/src/bin.ts +5 -0
  92. package/src/commands/add.ts +50 -0
  93. package/src/commands/init.ts +108 -0
  94. package/src/index.ts +23 -0
  95. package/src/templates/expo/Accordion.tsx +152 -0
  96. package/src/templates/expo/AlertDialog.tsx +147 -0
  97. package/src/templates/expo/Avatar.tsx +78 -0
  98. package/src/templates/expo/Badge.tsx +67 -0
  99. package/src/templates/expo/Button.tsx +53 -0
  100. package/src/templates/expo/Dropdown.tsx +100 -0
  101. package/src/templates/expo/Input.tsx +67 -0
  102. package/src/templates/expo/Toast.tsx +161 -0
  103. package/src/templates/expo/utils.ts +8 -0
  104. package/src/templates/flutter/Accordion.dart +142 -0
  105. package/src/templates/flutter/Alert.dart +96 -0
  106. package/src/templates/flutter/AlertDialog.dart +175 -0
  107. package/src/templates/flutter/Avatar.dart +82 -0
  108. package/src/templates/flutter/Badge.dart +89 -0
  109. package/src/templates/flutter/Button.dart +116 -0
  110. package/src/templates/flutter/Card.dart +91 -0
  111. package/src/templates/flutter/Input.dart +73 -0
  112. package/src/templates/flutter/Text.dart +87 -0
  113. package/src/templates/flutter/utils.dart +13 -0
  114. package/src/templates/web/Accordion.tsx +64 -0
  115. package/src/templates/web/Alert.tsx +71 -0
  116. package/src/templates/web/AlertDialog.tsx +164 -0
  117. package/src/templates/web/Avatar.tsx +51 -0
  118. package/src/templates/web/Badge.tsx +38 -0
  119. package/src/templates/web/Button.tsx +60 -0
  120. package/src/templates/web/Card.tsx +92 -0
  121. package/src/templates/web/Dropdown.tsx +198 -0
  122. package/src/templates/web/Input.tsx +21 -0
  123. package/src/templates/web/Tabs.tsx +66 -0
  124. package/src/templates/web/Toast.tsx +126 -0
  125. package/src/templates/web/utils.ts +6 -0
  126. package/src/utils/detect.ts +81 -0
  127. package/src/utils/fs.ts +32 -0
  128. package/tsconfig.json +17 -0
@@ -0,0 +1,126 @@
1
+ import * as React from "react";
2
+ import * as ToastPrimitive from "@radix-ui/react-toast";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import { X } from "lucide-react";
5
+ import { cn } from "./utils";
6
+
7
+ const ToastProvider = ToastPrimitive.Provider;
8
+
9
+ const ToastViewport = React.forwardRef<
10
+ React.ElementRef<typeof ToastPrimitive.Viewport>,
11
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Viewport>
12
+ >(({ className, ...props }, ref) => (
13
+ <ToastPrimitive.Viewport
14
+ ref={ref}
15
+ className={cn(
16
+ "fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ ));
22
+ ToastViewport.displayName = ToastPrimitive.Viewport.displayName;
23
+
24
+ const toastVariants = cva(
25
+ "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[animated=true]:duration-300 data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
26
+ {
27
+ variants: {
28
+ variant: {
29
+ default: "border bg-background text-foreground",
30
+ destructive:
31
+ "destructive group border-destructive bg-destructive text-destructive-foreground",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: "default",
36
+ },
37
+ }
38
+ );
39
+
40
+ const Toast = React.forwardRef<
41
+ React.ElementRef<typeof ToastPrimitive.Root>,
42
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Root> &
43
+ VariantProps<typeof toastVariants>
44
+ >(({ className, variant, ...props }, ref) => {
45
+ return (
46
+ <ToastPrimitive.Root
47
+ ref={ref}
48
+ className={cn(toastVariants({ variant }), className)}
49
+ {...props}
50
+ />
51
+ );
52
+ });
53
+ Toast.displayName = ToastPrimitive.Root.displayName;
54
+
55
+ const ToastAction = React.forwardRef<
56
+ React.ElementRef<typeof ToastPrimitive.Action>,
57
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Action>
58
+ >(({ className, ...props }, ref) => (
59
+ <ToastPrimitive.Action
60
+ ref={ref}
61
+ className={cn(
62
+ "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
63
+ className
64
+ )}
65
+ {...props}
66
+ />
67
+ ));
68
+ ToastAction.displayName = ToastPrimitive.Action.displayName;
69
+
70
+ const ToastClose = React.forwardRef<
71
+ React.ElementRef<typeof ToastPrimitive.Close>,
72
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Close>
73
+ >(({ className, ...props }, ref) => (
74
+ <ToastPrimitive.Close
75
+ ref={ref}
76
+ className={cn(
77
+ "absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50; group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
78
+ className
79
+ )}
80
+ toast-close=""
81
+ {...props}
82
+ >
83
+ <X className="h-4 w-4" />
84
+ </ToastPrimitive.Close>
85
+ ));
86
+ ToastClose.displayName = ToastPrimitive.Close.displayName;
87
+
88
+ const ToastTitle = React.forwardRef<
89
+ React.ElementRef<typeof ToastPrimitive.Title>,
90
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Title>
91
+ >(({ className, ...props }, ref) => (
92
+ <ToastPrimitive.Title
93
+ ref={ref}
94
+ className={cn("text-sm font-semibold", className)}
95
+ {...props}
96
+ />
97
+ ));
98
+ ToastTitle.displayName = ToastPrimitive.Title.displayName;
99
+
100
+ const ToastDescription = React.forwardRef<
101
+ React.ElementRef<typeof ToastPrimitive.Description>,
102
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Description>
103
+ >(({ className, ...props }, ref) => (
104
+ <ToastPrimitive.Description
105
+ ref={ref}
106
+ className={cn("text-sm opacity-90", className)}
107
+ {...props}
108
+ />
109
+ ));
110
+ ToastDescription.displayName = ToastPrimitive.Description.displayName;
111
+
112
+ type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
113
+
114
+ type ToastActionElement = React.ReactElement<typeof ToastAction>;
115
+
116
+ export {
117
+ type ToastProps,
118
+ type ToastActionElement,
119
+ ToastProvider,
120
+ ToastViewport,
121
+ Toast,
122
+ ToastTitle,
123
+ ToastDescription,
124
+ ToastClose,
125
+ ToastAction,
126
+ };
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,81 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+
4
+ /**
5
+ * Detect if the current project is an Expo project.
6
+ * Checks for presence of `expo` dependency in package.json
7
+ * or existence of `app.json` / `app.config.js`.
8
+ */
9
+ export async function detectExpoProject(cwd: string): Promise<boolean> {
10
+ // Check package.json dependencies
11
+ try {
12
+ const pkgPath = path.join(cwd, "package.json");
13
+ const pkgContent = await fs.promises.readFile(pkgPath, "utf8");
14
+ const pkg = JSON.parse(pkgContent);
15
+ const deps = {
16
+ ...(pkg.dependencies || {}),
17
+ ...(pkg.devDependencies || {}),
18
+ };
19
+ if (deps["expo"]) return true;
20
+ } catch {
21
+ // ignore errors, continue detection
22
+ }
23
+
24
+ // Check for app.json or app.config.js
25
+ const possibleFiles = ["app.json", "app.config.js", "app.config.ts"];
26
+ for (const file of possibleFiles) {
27
+ if (fs.existsSync(path.join(cwd, file))) return true;
28
+ }
29
+ return false;
30
+ }
31
+
32
+ /**
33
+ * Detect if the current project is a Flutter project.
34
+ * Checks for existence of `pubspec.yaml`.
35
+ */
36
+ export async function detectFlutterProject(cwd: string): Promise<boolean> {
37
+ return fs.existsSync(path.join(cwd, "pubspec.yaml"));
38
+ }
39
+
40
+ /**
41
+ * Detect if the current project is a Web project (React/Next.js/Vite).
42
+ */
43
+ export async function detectWebProject(cwd: string): Promise<boolean> {
44
+ const possibleFiles = [
45
+ "next.config.js",
46
+ "next.config.ts",
47
+ "vite.config.js",
48
+ "vite.config.ts",
49
+ "package.json",
50
+ ];
51
+ for (const file of possibleFiles) {
52
+ if (fs.existsSync(path.join(cwd, file))) {
53
+ if (file === "package.json") {
54
+ try {
55
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, file), "utf8"));
56
+ const deps = {
57
+ ...(pkg.dependencies || {}),
58
+ ...(pkg.devDependencies || {}),
59
+ };
60
+ return !!(deps["next"] || deps["react-dom"] || deps["vite"]);
61
+ } catch {
62
+ return false;
63
+ }
64
+ }
65
+ return true;
66
+ }
67
+ }
68
+ return false;
69
+ }
70
+
71
+ /**
72
+ * Detect the package manager used in the current directory.
73
+ */
74
+ export async function detectPackageManager(
75
+ cwd: string
76
+ ): Promise<"npm" | "pnpm" | "yarn" | "bun"> {
77
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
78
+ if (fs.existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
79
+ if (fs.existsSync(path.join(cwd, "bun.lockb"))) return "bun";
80
+ return "npm";
81
+ }
@@ -0,0 +1,32 @@
1
+ import { promises as fs } from "fs";
2
+ import path from "path";
3
+ import chalk from "chalk";
4
+
5
+ /**
6
+ * Safely copy a component template to the destination.
7
+ * If the destination file already exists, it will be skipped and a warning shown.
8
+ */
9
+ export async function copyComponent(src: string, dest: string): Promise<void> {
10
+ try {
11
+ // Ensure source exists
12
+ await fs.access(src);
13
+ } catch {
14
+ console.error(chalk.red(`Template not found at ${src}`));
15
+ return;
16
+ }
17
+
18
+ try {
19
+ await fs.access(dest);
20
+ console.log(
21
+ chalk.yellow(`File ${path.basename(dest)} already exists. Skipping copy.`)
22
+ );
23
+ return;
24
+ } catch {
25
+ // dest does not exist, proceed
26
+ }
27
+
28
+ // Ensure destination directory exists
29
+ await fs.mkdir(path.dirname(dest), { recursive: true });
30
+ await fs.copyFile(src, dest);
31
+ console.log(chalk.green(`Copied ${path.basename(src)} to ${dest}`));
32
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "CommonJS",
5
+ "declaration": true,
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "jsx": "react",
13
+ "types": ["node"]
14
+ },
15
+ "include": ["src"],
16
+ "exclude": ["src/templates"]
17
+ }