@jonelhatwell/arcade-games 1.0.0 → 1.0.1

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/dist/index.cjs CHANGED
@@ -20,11 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- SpaceDodger: () => spacedodger_default,
24
- Test: () => test_default
23
+ SpaceDodger: () => spacedodger_default
25
24
  });
26
25
  module.exports = __toCommonJS(index_exports);
27
26
 
27
+ // src/components/games/spacedodger/index.tsx
28
+ var import_react = require("react");
29
+
28
30
  // src/components/ui/button.tsx
29
31
  var import_react_slot = require("@radix-ui/react-slot");
30
32
  var import_class_variance_authority = require("class-variance-authority");
@@ -85,16 +87,8 @@ function Button({
85
87
  );
86
88
  }
87
89
 
88
- // src/components/games/test/index.tsx
89
- var import_jsx_runtime2 = require("react/jsx-runtime");
90
- var Test = () => {
91
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Button, { variant: "outline", children: "Button" }) });
92
- };
93
- var test_default = Test;
94
-
95
90
  // src/components/games/spacedodger/index.tsx
96
- var import_react = require("react");
97
- var import_jsx_runtime3 = require("react/jsx-runtime");
91
+ var import_jsx_runtime2 = require("react/jsx-runtime");
98
92
  var SpaceDodger = () => {
99
93
  const canvasRef = (0, import_react.useRef)(null);
100
94
  const [score, setScore] = (0, import_react.useState)(0);
@@ -167,23 +161,22 @@ var SpaceDodger = () => {
167
161
  window.removeEventListener("keyup", handleKeyUp);
168
162
  };
169
163
  }, [gameOver]);
170
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex flex-col items-center gap-4 p-4", children: [
171
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "text-xl font-bold", children: [
164
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4 p-4", children: [
165
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-xl font-bold", children: [
172
166
  "Score: ",
173
167
  score
174
168
  ] }),
175
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("canvas", { ref: canvasRef, width: "400", height: "400", className: "border-2 border-gray-300" }),
176
- gameOver && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "text-center", children: [
177
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xl font-bold text-red-500 mb-2", children: "Game Over!" }),
178
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { onClick: resetGame, children: "Play Again" })
169
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("canvas", { ref: canvasRef, width: "400", height: "400", className: "border-2 border-gray-300" }),
170
+ gameOver && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-center", children: [
171
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xl font-bold text-red-500 mb-2", children: "Game Over!" }),
172
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Button, { onClick: resetGame, children: "Play Again" })
179
173
  ] }),
180
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-600", children: "Use arrow keys to move" })
174
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-gray-600", children: "Use arrow keys to move" })
181
175
  ] });
182
176
  };
183
177
  var spacedodger_default = SpaceDodger;
184
178
  // Annotate the CommonJS export names for ESM import in node:
185
179
  0 && (module.exports = {
186
- SpaceDodger,
187
- Test
180
+ SpaceDodger
188
181
  });
189
182
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/ui/button.tsx","../src/lib/utils.ts","../src/components/games/test/index.tsx","../src/components/games/spacedodger/index.tsx"],"sourcesContent":["import \"./index.css\";\r\nexport { default as Test } from \"./components/games/test\";\r\nexport { default as SpaceDodger } from \"./components/games/spacedodger\";","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { clsx, type ClassValue } from \"clsx\"\r\nimport { twMerge } from \"tailwind-merge\"\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return twMerge(clsx(inputs))\r\n}","import { Button } from '@/components/ui/button'\r\n\r\nconst Test = () => {\r\n return (\r\n <div>\r\n <Button variant=\"outline\">Button</Button>\r\n </div>\r\n )\r\n}\r\n\r\nexport default Test","\r\nimport React, { useState, useEffect, useRef } from 'react';\r\nimport { Button } from '@/components/ui/button';\r\n\r\n\r\ninterface Position {\r\n x: number;\r\n y: number;\r\n}\r\n\r\n\r\ninterface Enemy extends Position {\r\n width: number;\r\n height: number;\r\n}\r\n\r\ninterface Player extends Position {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n\r\ninterface SpaceDodgerState {\r\n player: Player;\r\n enemies: Enemy[];\r\n frame: number;\r\n keys: Record<string, boolean>;\r\n}\r\n\r\nconst SpaceDodger: React.FC = () => {\r\n const canvasRef = useRef<HTMLCanvasElement>(null);\r\n const [score, setScore] = useState<number>(0);\r\n const [gameOver, setGameOver] = useState<boolean>(false);\r\n const gameStateRef = useRef<SpaceDodgerState>({\r\n player: { x: 200, y: 350, width: 30, height: 30 },\r\n enemies: [],\r\n frame: 0,\r\n keys: {}\r\n });\r\n\r\n const resetGame = (): void => {\r\n gameStateRef.current = {\r\n player: { x: 200, y: 350, width: 30, height: 30 },\r\n enemies: [],\r\n frame: 0,\r\n keys: {}\r\n };\r\n setScore(0);\r\n setGameOver(false);\r\n };\r\n\r\n useEffect(() => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) return;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n const state = gameStateRef.current;\r\n\r\n const handleKeyDown = (e: KeyboardEvent): void => { \r\n state.keys[e.key] = true; \r\n };\r\n const handleKeyUp = (e: KeyboardEvent): void => { \r\n state.keys[e.key] = false; \r\n };\r\n window.addEventListener('keydown', handleKeyDown);\r\n window.addEventListener('keyup', handleKeyUp);\r\n\r\n let animationId: number;\r\n const gameLoop = (): void => {\r\n if (gameOver) return;\r\n \r\n state.frame++;\r\n ctx.fillStyle = '#000';\r\n ctx.fillRect(0, 0, 400, 400);\r\n\r\n if (state.keys['ArrowLeft'] && state.player.x > 0) state.player.x -= 5;\r\n if (state.keys['ArrowRight'] && state.player.x < 370) state.player.x += 5;\r\n if (state.keys['ArrowUp'] && state.player.y > 0) state.player.y -= 5;\r\n if (state.keys['ArrowDown'] && state.player.y < 370) state.player.y += 5;\r\n\r\n ctx.fillStyle = '#0ea5e9';\r\n ctx.fillRect(state.player.x, state.player.y, state.player.width, state.player.height);\r\n\r\n if (state.frame % 40 === 0) {\r\n state.enemies.push({ x: Math.random() * 370, y: -20, width: 30, height: 30 });\r\n }\r\n\r\n state.enemies = state.enemies.filter(enemy => {\r\n enemy.y += 3;\r\n ctx.fillStyle = '#ef4444';\r\n ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);\r\n\r\n if (enemy.x < state.player.x + state.player.width &&\r\n enemy.x + enemy.width > state.player.x &&\r\n enemy.y < state.player.y + state.player.height &&\r\n enemy.y + enemy.height > state.player.y) {\r\n setGameOver(true);\r\n return false;\r\n }\r\n\r\n if (enemy.y > 400) {\r\n setScore(s => s + 1);\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n animationId = requestAnimationFrame(gameLoop);\r\n };\r\n \r\n if (!gameOver) gameLoop();\r\n\r\n return () => {\r\n cancelAnimationFrame(animationId);\r\n window.removeEventListener('keydown', handleKeyDown);\r\n window.removeEventListener('keyup', handleKeyUp);\r\n };\r\n }, [gameOver]);\r\n\r\n return (\r\n <div className=\"flex flex-col items-center gap-4 p-4\">\r\n <div className=\"text-xl font-bold\">Score: {score}</div>\r\n <canvas ref={canvasRef} width=\"400\" height=\"400\" className=\"border-2 border-gray-300\" />\r\n {gameOver && (\r\n <div className=\"text-center\">\r\n <p className=\"text-xl font-bold text-red-500 mb-2\">Game Over!</p>\r\n <Button onClick={resetGame}>Play Again</Button>\r\n </div>\r\n )}\r\n <p className=\"text-sm text-gray-600\">Use arrow keys to move</p>\r\n </div>\r\n );\r\n};\r\n\r\nexport default SpaceDodger;"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/games/spacedodger/index.tsx","../src/components/ui/button.tsx","../src/lib/utils.ts"],"sourcesContent":["import \"./index.css\";\r\nexport { default as SpaceDodger } from \"./components/games/spacedodger\";","\r\nimport React, { useState, useEffect, useRef } from 'react';\r\nimport { Button } from '@/components/ui/button';\r\n\r\n\r\ninterface Position {\r\n x: number;\r\n y: number;\r\n}\r\n\r\n\r\ninterface Enemy extends Position {\r\n width: number;\r\n height: number;\r\n}\r\n\r\ninterface Player extends Position {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n\r\ninterface SpaceDodgerState {\r\n player: Player;\r\n enemies: Enemy[];\r\n frame: number;\r\n keys: Record<string, boolean>;\r\n}\r\n\r\nconst SpaceDodger: React.FC = () => {\r\n const canvasRef = useRef<HTMLCanvasElement>(null);\r\n const [score, setScore] = useState<number>(0);\r\n const [gameOver, setGameOver] = useState<boolean>(false);\r\n const gameStateRef = useRef<SpaceDodgerState>({\r\n player: { x: 200, y: 350, width: 30, height: 30 },\r\n enemies: [],\r\n frame: 0,\r\n keys: {}\r\n });\r\n\r\n const resetGame = (): void => {\r\n gameStateRef.current = {\r\n player: { x: 200, y: 350, width: 30, height: 30 },\r\n enemies: [],\r\n frame: 0,\r\n keys: {}\r\n };\r\n setScore(0);\r\n setGameOver(false);\r\n };\r\n\r\n useEffect(() => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) return;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n const state = gameStateRef.current;\r\n\r\n const handleKeyDown = (e: KeyboardEvent): void => { \r\n state.keys[e.key] = true; \r\n };\r\n const handleKeyUp = (e: KeyboardEvent): void => { \r\n state.keys[e.key] = false; \r\n };\r\n window.addEventListener('keydown', handleKeyDown);\r\n window.addEventListener('keyup', handleKeyUp);\r\n\r\n let animationId: number;\r\n const gameLoop = (): void => {\r\n if (gameOver) return;\r\n \r\n state.frame++;\r\n ctx.fillStyle = '#000';\r\n ctx.fillRect(0, 0, 400, 400);\r\n\r\n if (state.keys['ArrowLeft'] && state.player.x > 0) state.player.x -= 5;\r\n if (state.keys['ArrowRight'] && state.player.x < 370) state.player.x += 5;\r\n if (state.keys['ArrowUp'] && state.player.y > 0) state.player.y -= 5;\r\n if (state.keys['ArrowDown'] && state.player.y < 370) state.player.y += 5;\r\n\r\n ctx.fillStyle = '#0ea5e9';\r\n ctx.fillRect(state.player.x, state.player.y, state.player.width, state.player.height);\r\n\r\n if (state.frame % 40 === 0) {\r\n state.enemies.push({ x: Math.random() * 370, y: -20, width: 30, height: 30 });\r\n }\r\n\r\n state.enemies = state.enemies.filter(enemy => {\r\n enemy.y += 3;\r\n ctx.fillStyle = '#ef4444';\r\n ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);\r\n\r\n if (enemy.x < state.player.x + state.player.width &&\r\n enemy.x + enemy.width > state.player.x &&\r\n enemy.y < state.player.y + state.player.height &&\r\n enemy.y + enemy.height > state.player.y) {\r\n setGameOver(true);\r\n return false;\r\n }\r\n\r\n if (enemy.y > 400) {\r\n setScore(s => s + 1);\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n animationId = requestAnimationFrame(gameLoop);\r\n };\r\n \r\n if (!gameOver) gameLoop();\r\n\r\n return () => {\r\n cancelAnimationFrame(animationId);\r\n window.removeEventListener('keydown', handleKeyDown);\r\n window.removeEventListener('keyup', handleKeyUp);\r\n };\r\n }, [gameOver]);\r\n\r\n return (\r\n <div className=\"flex flex-col items-center gap-4 p-4\">\r\n <div className=\"text-xl font-bold\">Score: {score}</div>\r\n <canvas ref={canvasRef} width=\"400\" height=\"400\" className=\"border-2 border-gray-300\" />\r\n {gameOver && (\r\n <div className=\"text-center\">\r\n <p className=\"text-xl font-bold text-red-500 mb-2\">Game Over!</p>\r\n <Button onClick={resetGame}>Play Again</Button>\r\n </div>\r\n )}\r\n <p className=\"text-sm text-gray-600\">Use arrow keys to move</p>\r\n </div>\r\n );\r\n};\r\n\r\nexport default SpaceDodger;","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { clsx, type ClassValue } from \"clsx\"\r\nimport { twMerge } from \"tailwind-merge\"\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return twMerge(clsx(inputs))\r\n}"],"mappings":"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","names":["import_jsx_runtime"]}
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ declare const SpaceDodger: React.FC;
4
+
5
+ export { SpaceDodger };
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ declare const SpaceDodger: React.FC;
4
+
5
+ export { SpaceDodger };
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ // src/components/games/spacedodger/index.tsx
2
+ import { useState, useEffect, useRef } from "react";
3
+
1
4
  // src/components/ui/button.tsx
2
5
  import { Slot } from "@radix-ui/react-slot";
3
6
  import { cva } from "class-variance-authority";
@@ -58,16 +61,8 @@ function Button({
58
61
  );
59
62
  }
60
63
 
61
- // src/components/games/test/index.tsx
62
- import { jsx as jsx2 } from "react/jsx-runtime";
63
- var Test = () => {
64
- return /* @__PURE__ */ jsx2("div", { children: /* @__PURE__ */ jsx2(Button, { variant: "outline", children: "Button" }) });
65
- };
66
- var test_default = Test;
67
-
68
64
  // src/components/games/spacedodger/index.tsx
69
- import { useState, useEffect, useRef } from "react";
70
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
65
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
71
66
  var SpaceDodger = () => {
72
67
  const canvasRef = useRef(null);
73
68
  const [score, setScore] = useState(0);
@@ -145,17 +140,16 @@ var SpaceDodger = () => {
145
140
  "Score: ",
146
141
  score
147
142
  ] }),
148
- /* @__PURE__ */ jsx3("canvas", { ref: canvasRef, width: "400", height: "400", className: "border-2 border-gray-300" }),
143
+ /* @__PURE__ */ jsx2("canvas", { ref: canvasRef, width: "400", height: "400", className: "border-2 border-gray-300" }),
149
144
  gameOver && /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
150
- /* @__PURE__ */ jsx3("p", { className: "text-xl font-bold text-red-500 mb-2", children: "Game Over!" }),
151
- /* @__PURE__ */ jsx3(Button, { onClick: resetGame, children: "Play Again" })
145
+ /* @__PURE__ */ jsx2("p", { className: "text-xl font-bold text-red-500 mb-2", children: "Game Over!" }),
146
+ /* @__PURE__ */ jsx2(Button, { onClick: resetGame, children: "Play Again" })
152
147
  ] }),
153
- /* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-600", children: "Use arrow keys to move" })
148
+ /* @__PURE__ */ jsx2("p", { className: "text-sm text-gray-600", children: "Use arrow keys to move" })
154
149
  ] });
155
150
  };
156
151
  var spacedodger_default = SpaceDodger;
157
152
  export {
158
- spacedodger_default as SpaceDodger,
159
- test_default as Test
153
+ spacedodger_default as SpaceDodger
160
154
  };
161
155
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ui/button.tsx","../src/lib/utils.ts","../src/components/games/test/index.tsx","../src/components/games/spacedodger/index.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { clsx, type ClassValue } from \"clsx\"\r\nimport { twMerge } from \"tailwind-merge\"\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return twMerge(clsx(inputs))\r\n}","import { Button } from '@/components/ui/button'\r\n\r\nconst Test = () => {\r\n return (\r\n <div>\r\n <Button variant=\"outline\">Button</Button>\r\n </div>\r\n )\r\n}\r\n\r\nexport default Test","\r\nimport React, { useState, useEffect, useRef } from 'react';\r\nimport { Button } from '@/components/ui/button';\r\n\r\n\r\ninterface Position {\r\n x: number;\r\n y: number;\r\n}\r\n\r\n\r\ninterface Enemy extends Position {\r\n width: number;\r\n height: number;\r\n}\r\n\r\ninterface Player extends Position {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n\r\ninterface SpaceDodgerState {\r\n player: Player;\r\n enemies: Enemy[];\r\n frame: number;\r\n keys: Record<string, boolean>;\r\n}\r\n\r\nconst SpaceDodger: React.FC = () => {\r\n const canvasRef = useRef<HTMLCanvasElement>(null);\r\n const [score, setScore] = useState<number>(0);\r\n const [gameOver, setGameOver] = useState<boolean>(false);\r\n const gameStateRef = useRef<SpaceDodgerState>({\r\n player: { x: 200, y: 350, width: 30, height: 30 },\r\n enemies: [],\r\n frame: 0,\r\n keys: {}\r\n });\r\n\r\n const resetGame = (): void => {\r\n gameStateRef.current = {\r\n player: { x: 200, y: 350, width: 30, height: 30 },\r\n enemies: [],\r\n frame: 0,\r\n keys: {}\r\n };\r\n setScore(0);\r\n setGameOver(false);\r\n };\r\n\r\n useEffect(() => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) return;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n const state = gameStateRef.current;\r\n\r\n const handleKeyDown = (e: KeyboardEvent): void => { \r\n state.keys[e.key] = true; \r\n };\r\n const handleKeyUp = (e: KeyboardEvent): void => { \r\n state.keys[e.key] = false; \r\n };\r\n window.addEventListener('keydown', handleKeyDown);\r\n window.addEventListener('keyup', handleKeyUp);\r\n\r\n let animationId: number;\r\n const gameLoop = (): void => {\r\n if (gameOver) return;\r\n \r\n state.frame++;\r\n ctx.fillStyle = '#000';\r\n ctx.fillRect(0, 0, 400, 400);\r\n\r\n if (state.keys['ArrowLeft'] && state.player.x > 0) state.player.x -= 5;\r\n if (state.keys['ArrowRight'] && state.player.x < 370) state.player.x += 5;\r\n if (state.keys['ArrowUp'] && state.player.y > 0) state.player.y -= 5;\r\n if (state.keys['ArrowDown'] && state.player.y < 370) state.player.y += 5;\r\n\r\n ctx.fillStyle = '#0ea5e9';\r\n ctx.fillRect(state.player.x, state.player.y, state.player.width, state.player.height);\r\n\r\n if (state.frame % 40 === 0) {\r\n state.enemies.push({ x: Math.random() * 370, y: -20, width: 30, height: 30 });\r\n }\r\n\r\n state.enemies = state.enemies.filter(enemy => {\r\n enemy.y += 3;\r\n ctx.fillStyle = '#ef4444';\r\n ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);\r\n\r\n if (enemy.x < state.player.x + state.player.width &&\r\n enemy.x + enemy.width > state.player.x &&\r\n enemy.y < state.player.y + state.player.height &&\r\n enemy.y + enemy.height > state.player.y) {\r\n setGameOver(true);\r\n return false;\r\n }\r\n\r\n if (enemy.y > 400) {\r\n setScore(s => s + 1);\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n animationId = requestAnimationFrame(gameLoop);\r\n };\r\n \r\n if (!gameOver) gameLoop();\r\n\r\n return () => {\r\n cancelAnimationFrame(animationId);\r\n window.removeEventListener('keydown', handleKeyDown);\r\n window.removeEventListener('keyup', handleKeyUp);\r\n };\r\n }, [gameOver]);\r\n\r\n return (\r\n <div className=\"flex flex-col items-center gap-4 p-4\">\r\n <div className=\"text-xl font-bold\">Score: {score}</div>\r\n <canvas ref={canvasRef} width=\"400\" height=\"400\" className=\"border-2 border-gray-300\" />\r\n {gameOver && (\r\n <div className=\"text-center\">\r\n <p className=\"text-xl font-bold text-red-500 mb-2\">Game Over!</p>\r\n <Button onClick={resetGame}>Play Again</Button>\r\n </div>\r\n )}\r\n <p className=\"text-sm text-gray-600\">Use arrow keys to move</p>\r\n </div>\r\n );\r\n};\r\n\r\nexport default SpaceDodger;"],"mappings":"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","names":["jsx","jsx"]}
1
+ {"version":3,"sources":["../src/components/games/spacedodger/index.tsx","../src/components/ui/button.tsx","../src/lib/utils.ts"],"sourcesContent":["\r\nimport React, { useState, useEffect, useRef } from 'react';\r\nimport { Button } from '@/components/ui/button';\r\n\r\n\r\ninterface Position {\r\n x: number;\r\n y: number;\r\n}\r\n\r\n\r\ninterface Enemy extends Position {\r\n width: number;\r\n height: number;\r\n}\r\n\r\ninterface Player extends Position {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n\r\ninterface SpaceDodgerState {\r\n player: Player;\r\n enemies: Enemy[];\r\n frame: number;\r\n keys: Record<string, boolean>;\r\n}\r\n\r\nconst SpaceDodger: React.FC = () => {\r\n const canvasRef = useRef<HTMLCanvasElement>(null);\r\n const [score, setScore] = useState<number>(0);\r\n const [gameOver, setGameOver] = useState<boolean>(false);\r\n const gameStateRef = useRef<SpaceDodgerState>({\r\n player: { x: 200, y: 350, width: 30, height: 30 },\r\n enemies: [],\r\n frame: 0,\r\n keys: {}\r\n });\r\n\r\n const resetGame = (): void => {\r\n gameStateRef.current = {\r\n player: { x: 200, y: 350, width: 30, height: 30 },\r\n enemies: [],\r\n frame: 0,\r\n keys: {}\r\n };\r\n setScore(0);\r\n setGameOver(false);\r\n };\r\n\r\n useEffect(() => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) return;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n const state = gameStateRef.current;\r\n\r\n const handleKeyDown = (e: KeyboardEvent): void => { \r\n state.keys[e.key] = true; \r\n };\r\n const handleKeyUp = (e: KeyboardEvent): void => { \r\n state.keys[e.key] = false; \r\n };\r\n window.addEventListener('keydown', handleKeyDown);\r\n window.addEventListener('keyup', handleKeyUp);\r\n\r\n let animationId: number;\r\n const gameLoop = (): void => {\r\n if (gameOver) return;\r\n \r\n state.frame++;\r\n ctx.fillStyle = '#000';\r\n ctx.fillRect(0, 0, 400, 400);\r\n\r\n if (state.keys['ArrowLeft'] && state.player.x > 0) state.player.x -= 5;\r\n if (state.keys['ArrowRight'] && state.player.x < 370) state.player.x += 5;\r\n if (state.keys['ArrowUp'] && state.player.y > 0) state.player.y -= 5;\r\n if (state.keys['ArrowDown'] && state.player.y < 370) state.player.y += 5;\r\n\r\n ctx.fillStyle = '#0ea5e9';\r\n ctx.fillRect(state.player.x, state.player.y, state.player.width, state.player.height);\r\n\r\n if (state.frame % 40 === 0) {\r\n state.enemies.push({ x: Math.random() * 370, y: -20, width: 30, height: 30 });\r\n }\r\n\r\n state.enemies = state.enemies.filter(enemy => {\r\n enemy.y += 3;\r\n ctx.fillStyle = '#ef4444';\r\n ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);\r\n\r\n if (enemy.x < state.player.x + state.player.width &&\r\n enemy.x + enemy.width > state.player.x &&\r\n enemy.y < state.player.y + state.player.height &&\r\n enemy.y + enemy.height > state.player.y) {\r\n setGameOver(true);\r\n return false;\r\n }\r\n\r\n if (enemy.y > 400) {\r\n setScore(s => s + 1);\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n animationId = requestAnimationFrame(gameLoop);\r\n };\r\n \r\n if (!gameOver) gameLoop();\r\n\r\n return () => {\r\n cancelAnimationFrame(animationId);\r\n window.removeEventListener('keydown', handleKeyDown);\r\n window.removeEventListener('keyup', handleKeyUp);\r\n };\r\n }, [gameOver]);\r\n\r\n return (\r\n <div className=\"flex flex-col items-center gap-4 p-4\">\r\n <div className=\"text-xl font-bold\">Score: {score}</div>\r\n <canvas ref={canvasRef} width=\"400\" height=\"400\" className=\"border-2 border-gray-300\" />\r\n {gameOver && (\r\n <div className=\"text-center\">\r\n <p className=\"text-xl font-bold text-red-500 mb-2\">Game Over!</p>\r\n <Button onClick={resetGame}>Play Again</Button>\r\n </div>\r\n )}\r\n <p className=\"text-sm text-gray-600\">Use arrow keys to move</p>\r\n </div>\r\n );\r\n};\r\n\r\nexport default SpaceDodger;","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { clsx, type ClassValue } from \"clsx\"\r\nimport { twMerge } from \"tailwind-merge\"\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return twMerge(clsx(inputs))\r\n}"],"mappings":"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","names":["jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jonelhatwell/arcade-games",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -14,10 +14,10 @@
14
14
  },
15
15
  "./styles": "./dist/index.css"
16
16
  },
17
- "scripts": {
18
- "build": "tsup",
19
- "dev": "tsup --watch"
20
- },
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
21
  "peerDependencies": {
22
22
  "react": "^18 || ^19",
23
23
  "react-dom": "^18 || ^19"
@@ -49,5 +49,9 @@
49
49
  "typescript": "~5.9.3",
50
50
  "typescript-eslint": "^8.46.4",
51
51
  "vite": "^7.2.4"
52
+ },
53
+ "scripts": {
54
+ "build": "tsup",
55
+ "dev": "tsup --watch"
52
56
  }
53
- }
57
+ }
package/components.json DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "new-york",
4
- "rsc": false,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "",
8
- "css": "src/index.css",
9
- "baseColor": "zinc",
10
- "cssVariables": true,
11
- "prefix": ""
12
- },
13
- "aliases": {
14
- "components": "@/components",
15
- "utils": "@/lib/utils",
16
- "ui": "@/components/ui",
17
- "lib": "@/lib",
18
- "hooks": "@/hooks"
19
- },
20
- "iconLibrary": "lucide"
21
- }
package/eslint.config.js DELETED
@@ -1,23 +0,0 @@
1
- import js from '@eslint/js'
2
- import globals from 'globals'
3
- import reactHooks from 'eslint-plugin-react-hooks'
4
- import reactRefresh from 'eslint-plugin-react-refresh'
5
- import tseslint from 'typescript-eslint'
6
- import { defineConfig, globalIgnores } from 'eslint/config'
7
-
8
- export default defineConfig([
9
- globalIgnores(['dist']),
10
- {
11
- files: ['**/*.{ts,tsx}'],
12
- extends: [
13
- js.configs.recommended,
14
- tseslint.configs.recommended,
15
- reactHooks.configs.flat.recommended,
16
- reactRefresh.configs.vite,
17
- ],
18
- languageOptions: {
19
- ecmaVersion: 2020,
20
- globals: globals.browser,
21
- },
22
- },
23
- ])
@@ -1,5 +0,0 @@
1
- export default {
2
- plugins: {
3
- "@tailwindcss/postcss": {},
4
- }
5
- }
package/public/vite.svg DELETED
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -1,135 +0,0 @@
1
-
2
- import React, { useState, useEffect, useRef } from 'react';
3
- import { Button } from '@/components/ui/button';
4
-
5
-
6
- interface Position {
7
- x: number;
8
- y: number;
9
- }
10
-
11
-
12
- interface Enemy extends Position {
13
- width: number;
14
- height: number;
15
- }
16
-
17
- interface Player extends Position {
18
- width: number;
19
- height: number;
20
- }
21
-
22
-
23
- interface SpaceDodgerState {
24
- player: Player;
25
- enemies: Enemy[];
26
- frame: number;
27
- keys: Record<string, boolean>;
28
- }
29
-
30
- const SpaceDodger: React.FC = () => {
31
- const canvasRef = useRef<HTMLCanvasElement>(null);
32
- const [score, setScore] = useState<number>(0);
33
- const [gameOver, setGameOver] = useState<boolean>(false);
34
- const gameStateRef = useRef<SpaceDodgerState>({
35
- player: { x: 200, y: 350, width: 30, height: 30 },
36
- enemies: [],
37
- frame: 0,
38
- keys: {}
39
- });
40
-
41
- const resetGame = (): void => {
42
- gameStateRef.current = {
43
- player: { x: 200, y: 350, width: 30, height: 30 },
44
- enemies: [],
45
- frame: 0,
46
- keys: {}
47
- };
48
- setScore(0);
49
- setGameOver(false);
50
- };
51
-
52
- useEffect(() => {
53
- const canvas = canvasRef.current;
54
- if (!canvas) return;
55
- const ctx = canvas.getContext('2d');
56
- if (!ctx) return;
57
- const state = gameStateRef.current;
58
-
59
- const handleKeyDown = (e: KeyboardEvent): void => {
60
- state.keys[e.key] = true;
61
- };
62
- const handleKeyUp = (e: KeyboardEvent): void => {
63
- state.keys[e.key] = false;
64
- };
65
- window.addEventListener('keydown', handleKeyDown);
66
- window.addEventListener('keyup', handleKeyUp);
67
-
68
- let animationId: number;
69
- const gameLoop = (): void => {
70
- if (gameOver) return;
71
-
72
- state.frame++;
73
- ctx.fillStyle = '#000';
74
- ctx.fillRect(0, 0, 400, 400);
75
-
76
- if (state.keys['ArrowLeft'] && state.player.x > 0) state.player.x -= 5;
77
- if (state.keys['ArrowRight'] && state.player.x < 370) state.player.x += 5;
78
- if (state.keys['ArrowUp'] && state.player.y > 0) state.player.y -= 5;
79
- if (state.keys['ArrowDown'] && state.player.y < 370) state.player.y += 5;
80
-
81
- ctx.fillStyle = '#0ea5e9';
82
- ctx.fillRect(state.player.x, state.player.y, state.player.width, state.player.height);
83
-
84
- if (state.frame % 40 === 0) {
85
- state.enemies.push({ x: Math.random() * 370, y: -20, width: 30, height: 30 });
86
- }
87
-
88
- state.enemies = state.enemies.filter(enemy => {
89
- enemy.y += 3;
90
- ctx.fillStyle = '#ef4444';
91
- ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);
92
-
93
- if (enemy.x < state.player.x + state.player.width &&
94
- enemy.x + enemy.width > state.player.x &&
95
- enemy.y < state.player.y + state.player.height &&
96
- enemy.y + enemy.height > state.player.y) {
97
- setGameOver(true);
98
- return false;
99
- }
100
-
101
- if (enemy.y > 400) {
102
- setScore(s => s + 1);
103
- return false;
104
- }
105
- return true;
106
- });
107
-
108
- animationId = requestAnimationFrame(gameLoop);
109
- };
110
-
111
- if (!gameOver) gameLoop();
112
-
113
- return () => {
114
- cancelAnimationFrame(animationId);
115
- window.removeEventListener('keydown', handleKeyDown);
116
- window.removeEventListener('keyup', handleKeyUp);
117
- };
118
- }, [gameOver]);
119
-
120
- return (
121
- <div className="flex flex-col items-center gap-4 p-4">
122
- <div className="text-xl font-bold">Score: {score}</div>
123
- <canvas ref={canvasRef} width="400" height="400" className="border-2 border-gray-300" />
124
- {gameOver && (
125
- <div className="text-center">
126
- <p className="text-xl font-bold text-red-500 mb-2">Game Over!</p>
127
- <Button onClick={resetGame}>Play Again</Button>
128
- </div>
129
- )}
130
- <p className="text-sm text-gray-600">Use arrow keys to move</p>
131
- </div>
132
- );
133
- };
134
-
135
- export default SpaceDodger;
@@ -1,62 +0,0 @@
1
- import * as React from "react"
2
- import { Slot } from "@radix-ui/react-slot"
3
- import { cva, type VariantProps } from "class-variance-authority"
4
-
5
- import { cn } from "@/lib/utils"
6
-
7
- const buttonVariants = cva(
8
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9
- {
10
- variants: {
11
- variant: {
12
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
- destructive:
14
- "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
15
- outline:
16
- "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
17
- secondary:
18
- "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19
- ghost:
20
- "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
21
- link: "text-primary underline-offset-4 hover:underline",
22
- },
23
- size: {
24
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
25
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
26
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
27
- icon: "size-9",
28
- "icon-sm": "size-8",
29
- "icon-lg": "size-10",
30
- },
31
- },
32
- defaultVariants: {
33
- variant: "default",
34
- size: "default",
35
- },
36
- }
37
- )
38
-
39
- function Button({
40
- className,
41
- variant = "default",
42
- size = "default",
43
- asChild = false,
44
- ...props
45
- }: React.ComponentProps<"button"> &
46
- VariantProps<typeof buttonVariants> & {
47
- asChild?: boolean
48
- }) {
49
- const Comp = asChild ? Slot : "button"
50
-
51
- return (
52
- <Comp
53
- data-slot="button"
54
- data-variant={variant}
55
- data-size={size}
56
- className={cn(buttonVariants({ variant, size, className }))}
57
- {...props}
58
- />
59
- )
60
- }
61
-
62
- export { Button, buttonVariants }
@@ -1,92 +0,0 @@
1
- import * as React from "react"
2
-
3
- import { cn } from "@/lib/utils"
4
-
5
- function Card({ className, ...props }: React.ComponentProps<"div">) {
6
- return (
7
- <div
8
- data-slot="card"
9
- className={cn(
10
- "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
11
- className
12
- )}
13
- {...props}
14
- />
15
- )
16
- }
17
-
18
- function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19
- return (
20
- <div
21
- data-slot="card-header"
22
- className={cn(
23
- "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
24
- className
25
- )}
26
- {...props}
27
- />
28
- )
29
- }
30
-
31
- function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32
- return (
33
- <div
34
- data-slot="card-title"
35
- className={cn("leading-none font-semibold", className)}
36
- {...props}
37
- />
38
- )
39
- }
40
-
41
- function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42
- return (
43
- <div
44
- data-slot="card-description"
45
- className={cn("text-muted-foreground text-sm", className)}
46
- {...props}
47
- />
48
- )
49
- }
50
-
51
- function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52
- return (
53
- <div
54
- data-slot="card-action"
55
- className={cn(
56
- "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
57
- className
58
- )}
59
- {...props}
60
- />
61
- )
62
- }
63
-
64
- function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65
- return (
66
- <div
67
- data-slot="card-content"
68
- className={cn("px-6", className)}
69
- {...props}
70
- />
71
- )
72
- }
73
-
74
- function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75
- return (
76
- <div
77
- data-slot="card-footer"
78
- className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
79
- {...props}
80
- />
81
- )
82
- }
83
-
84
- export {
85
- Card,
86
- CardHeader,
87
- CardFooter,
88
- CardTitle,
89
- CardAction,
90
- CardDescription,
91
- CardContent,
92
- }
package/src/index.css DELETED
@@ -1,123 +0,0 @@
1
- @import "tailwindcss";
2
- @import "tw-animate-css";
3
-
4
- @custom-variant dark (&:is(.dark *));
5
-
6
- :root {
7
- --background: oklch(1 0 0);
8
- --foreground: oklch(0.145 0 0);
9
- --card: oklch(1 0 0);
10
- --card-foreground: oklch(0.145 0 0);
11
- --popover: oklch(1 0 0);
12
- --popover-foreground: oklch(0.145 0 0);
13
- --primary: oklch(0.205 0 0);
14
- --primary-foreground: oklch(0.985 0 0);
15
- --secondary: oklch(0.97 0 0);
16
- --secondary-foreground: oklch(0.205 0 0);
17
- --muted: oklch(0.97 0 0);
18
- --muted-foreground: oklch(0.556 0 0);
19
- --accent: oklch(0.97 0 0);
20
- --accent-foreground: oklch(0.205 0 0);
21
- --destructive: oklch(0.577 0.245 27.325);
22
- --destructive-foreground: oklch(0.577 0.245 27.325);
23
- --border: oklch(0.922 0 0);
24
- --input: oklch(0.922 0 0);
25
- --ring: oklch(0.708 0 0);
26
- --chart-1: oklch(0.646 0.222 41.116);
27
- --chart-2: oklch(0.6 0.118 184.704);
28
- --chart-3: oklch(0.398 0.07 227.392);
29
- --chart-4: oklch(0.828 0.189 84.429);
30
- --chart-5: oklch(0.769 0.188 70.08);
31
- --radius: 0.625rem;
32
- --sidebar: oklch(0.985 0 0);
33
- --sidebar-foreground: oklch(0.145 0 0);
34
- --sidebar-primary: oklch(0.205 0 0);
35
- --sidebar-primary-foreground: oklch(0.985 0 0);
36
- --sidebar-accent: oklch(0.97 0 0);
37
- --sidebar-accent-foreground: oklch(0.205 0 0);
38
- --sidebar-border: oklch(0.922 0 0);
39
- --sidebar-ring: oklch(0.708 0 0);
40
- }
41
-
42
- .dark {
43
- --background: oklch(0.145 0 0);
44
- --foreground: oklch(0.985 0 0);
45
- --card: oklch(0.145 0 0);
46
- --card-foreground: oklch(0.985 0 0);
47
- --popover: oklch(0.145 0 0);
48
- --popover-foreground: oklch(0.985 0 0);
49
- --primary: oklch(0.985 0 0);
50
- --primary-foreground: oklch(0.205 0 0);
51
- --secondary: oklch(0.269 0 0);
52
- --secondary-foreground: oklch(0.985 0 0);
53
- --muted: oklch(0.269 0 0);
54
- --muted-foreground: oklch(0.708 0 0);
55
- --accent: oklch(0.269 0 0);
56
- --accent-foreground: oklch(0.985 0 0);
57
- --destructive: oklch(0.396 0.141 25.723);
58
- --destructive-foreground: oklch(0.637 0.237 25.331);
59
- --border: oklch(0.269 0 0);
60
- --input: oklch(0.269 0 0);
61
- --ring: oklch(0.439 0 0);
62
- --chart-1: oklch(0.488 0.243 264.376);
63
- --chart-2: oklch(0.696 0.17 162.48);
64
- --chart-3: oklch(0.769 0.188 70.08);
65
- --chart-4: oklch(0.627 0.265 303.9);
66
- --chart-5: oklch(0.645 0.246 16.439);
67
- --sidebar: oklch(0.205 0 0);
68
- --sidebar-foreground: oklch(0.985 0 0);
69
- --sidebar-primary: oklch(0.488 0.243 264.376);
70
- --sidebar-primary-foreground: oklch(0.985 0 0);
71
- --sidebar-accent: oklch(0.269 0 0);
72
- --sidebar-accent-foreground: oklch(0.985 0 0);
73
- --sidebar-border: oklch(0.269 0 0);
74
- --sidebar-ring: oklch(0.439 0 0);
75
- }
76
-
77
- @theme inline {
78
- --color-background: var(--background);
79
- --color-foreground: var(--foreground);
80
- --color-card: var(--card);
81
- --color-card-foreground: var(--card-foreground);
82
- --color-popover: var(--popover);
83
- --color-popover-foreground: var(--popover-foreground);
84
- --color-primary: var(--primary);
85
- --color-primary-foreground: var(--primary-foreground);
86
- --color-secondary: var(--secondary);
87
- --color-secondary-foreground: var(--secondary-foreground);
88
- --color-muted: var(--muted);
89
- --color-muted-foreground: var(--muted-foreground);
90
- --color-accent: var(--accent);
91
- --color-accent-foreground: var(--accent-foreground);
92
- --color-destructive: var(--destructive);
93
- --color-destructive-foreground: var(--destructive-foreground);
94
- --color-border: var(--border);
95
- --color-input: var(--input);
96
- --color-ring: var(--ring);
97
- --color-chart-1: var(--chart-1);
98
- --color-chart-2: var(--chart-2);
99
- --color-chart-3: var(--chart-3);
100
- --color-chart-4: var(--chart-4);
101
- --color-chart-5: var(--chart-5);
102
- --radius-sm: calc(var(--radius) - 4px);
103
- --radius-md: calc(var(--radius) - 2px);
104
- --radius-lg: var(--radius);
105
- --radius-xl: calc(var(--radius) + 4px);
106
- --color-sidebar: var(--sidebar);
107
- --color-sidebar-foreground: var(--sidebar-foreground);
108
- --color-sidebar-primary: var(--sidebar-primary);
109
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
110
- --color-sidebar-accent: var(--sidebar-accent);
111
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
112
- --color-sidebar-border: var(--sidebar-border);
113
- --color-sidebar-ring: var(--sidebar-ring);
114
- }
115
-
116
- @layer base {
117
- * {
118
- @apply border-border outline-ring/50;
119
- }
120
- body {
121
- @apply bg-background text-foreground;
122
- }
123
- }
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- import "./index.css";
2
- export { default as Test } from "./components/games/test";
3
- export { default as SpaceDodger } from "./components/games/spacedodger";
package/src/lib/utils.ts DELETED
@@ -1,6 +0,0 @@
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
- }
@@ -1 +0,0 @@
1
- declare module "*.css";
@@ -1,7 +0,0 @@
1
- export default {
2
- content: [
3
- "./src/**/*.{ts,tsx,js,jsx}"
4
- ], // all source files
5
- theme: {},
6
- plugins: [],
7
- };
package/tsconfig.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "jsx": "react-jsx",
6
- "strict": true,
7
- "moduleResolution": "Bundler",
8
- "skipLibCheck": true,
9
- "baseUrl": ".",
10
- "paths": {
11
- "@/*": ["./src/*"]
12
- }
13
- },
14
- "include": ["src"]
15
- }
package/tsup.config.ts DELETED
@@ -1,17 +0,0 @@
1
- import { defineConfig } from "tsup";
2
-
3
- export default defineConfig({
4
- entry: ["src/index.ts"],
5
- format: ["esm", "cjs"],
6
- dts: true,
7
- clean: true,
8
- sourcemap: true,
9
- external: ["react", "react-dom"],
10
- outDir: "dist",
11
- esbuildOptions(options) {
12
- options.loader = {
13
- ...options.loader,
14
- ".css": "css",
15
- };
16
- },
17
- });