create-zoijs 0.1.2 → 0.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  All notable changes to `create-zoijs` are documented here.
4
4
 
5
+ ## 0.1.3 — 2026-06-26
6
+
7
+ Three new templates (now five total). No change to existing templates or the CLI
8
+ API; `app` stays the default.
9
+
10
+ - **`typescript`** — the counter as **type-checked JavaScript**: `// @ts-check` +
11
+ a strict `tsconfig.json` + `npm run typecheck` (`tsc --noEmit`) give full
12
+ TypeScript safety using `@zoijs/core`'s shipped types, with **no build step** (the
13
+ browser runs the `.js` as-is). Keeps the dev server on 7310.
14
+ - **`minimal`** — the smallest scaffold: two flat files (`index.html` + `app.js`)
15
+ loading `@zoijs/core` from a CDN. No `package.json`, no install, no dev server —
16
+ run with `npx serve . -l 7310`.
17
+ - **`library`** — a starter for authoring a Zoijs-based package: `src/index.js` +
18
+ hand-written `index.d.ts`, an `exports`/`types` `package.json` with a peer
19
+ dependency on `@zoijs/core`, and a `node:test` suite — the shape the official
20
+ optional packages use.
21
+ - The scaffolder now treats `.ts`/`.d.ts` as text (token substitution), and the
22
+ CLI's own `npm test` targets its own test file so it no longer runs the
23
+ templates' bundled test files.
24
+
5
25
  ## 0.1.2 — 2026-06-26
6
26
 
7
27
  Dev-server output polish. No CLI API changes; same zero-dependency server on the
package/README.md CHANGED
@@ -56,15 +56,24 @@ one.
56
56
  ## Templates
57
57
 
58
58
  ```bash
59
- npm create zoijs@latest my-app # default: the "app" template
60
- npm create zoijs@latest my-app --template basic # a minimal counter
61
- npm create zoijs@latest my-app --template app # a polished project dashboard
59
+ npm create zoijs@latest my-app # default: the "app" template
60
+ npm create zoijs@latest my-app --template app # a polished project dashboard
61
+ npm create zoijs@latest my-app --template basic # a basic counter
62
+ npm create zoijs@latest my-app --template typescript # type-checked JS, no build step
63
+ npm create zoijs@latest my-app --template minimal # two flat files, CDN, no install
64
+ npm create zoijs@latest my-app --template library # author a Zoijs-based package
62
65
  ```
63
66
 
64
67
  - **`app`** (default) — a polished project dashboard (hero, stat cards, filters,
65
68
  empty state) showing `html`, `mount`, `createState`, `computed`, `each`,
66
69
  conditional rendering, and parent⇄child component communication.
67
- - **`basic`** — a minimal counter, the smallest possible Zoijs app.
70
+ - **`basic`** — a basic counter, a small local app with a dev server.
71
+ - **`typescript`** — the counter as type-checked JavaScript (`// @ts-check` +
72
+ strict `tsconfig.json` + `npm run typecheck`). Full TS safety, **no build step**.
73
+ - **`minimal`** — the smallest scaffold: two flat files loading `@zoijs/core` from a
74
+ CDN. No install, no dev server — run with `npx serve . -l 7310`.
75
+ - **`library`** — a starter for authoring a Zoijs-based package: `src` + `.d.ts`,
76
+ `exports`/`types`, a peer dep on `@zoijs/core`, and a `node:test` suite.
68
77
 
69
78
  ## What it does
70
79
 
@@ -17,7 +17,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
17
17
 
18
18
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
19
 
20
- export const TEMPLATES = ["basic", "app"];
20
+ export const TEMPLATES = ["basic", "app", "typescript", "minimal", "library"];
21
21
  export const DEFAULT_TEMPLATE = "app";
22
22
  const TEMPLATES_DIR = path.join(__dirname, "..", "templates");
23
23
 
@@ -75,7 +75,7 @@ export function ensureTargetAvailable(targetDir) {
75
75
  }
76
76
  }
77
77
 
78
- const TEXT_EXT = new Set([".js", ".mjs", ".html", ".css", ".json", ".md", ".txt", ".svg"]);
78
+ const TEXT_EXT = new Set([".js", ".ts", ".mjs", ".html", ".css", ".json", ".md", ".txt", ".svg"]);
79
79
  const isText = (file) => file === "_gitignore" || TEXT_EXT.has(path.extname(file));
80
80
 
81
81
  function applyTokens(content, tokens) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-zoijs",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Create a new Zoijs app with one command. Plain HTML, CSS, and JavaScript — no build step.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,6 +38,6 @@
38
38
  "no-jsx"
39
39
  ],
40
40
  "scripts": {
41
- "test": "node --test"
41
+ "test": "node --test tests/create.test.js"
42
42
  }
43
43
  }
@@ -0,0 +1,48 @@
1
+ # {{APP_NAME}}
2
+
3
+ A small library built on [Zoijs](https://zoijs.dev) — plain JavaScript, types
4
+ shipped as `.d.ts`, **no build step.**
5
+
6
+ This is the same shape the official optional packages (`@zoijs/forms`,
7
+ `@zoijs/storage`, …) use: one tiny module that imports **only** the core's public
8
+ API, with hand-written type definitions and a test suite.
9
+
10
+ ## Develop
11
+
12
+ ```bash
13
+ npm install
14
+ npm test # behavior (node --test)
15
+ npm run test:types # type-check src against the .d.ts (tsc --noEmit)
16
+ ```
17
+
18
+ There's nothing to compile — consumers import your `src/index.js` directly via an
19
+ import map or a bundler of their choosing.
20
+
21
+ ## Layout
22
+
23
+ ```
24
+ {{APP_NAME}}/
25
+ package.json name, exports, types, peer dep on @zoijs/core
26
+ tsconfig.json strict, checkJs, noEmit (type-check only)
27
+ src/
28
+ index.js your library (imports only @zoijs/core's public API)
29
+ index.d.ts hand-written types (imports core types so they never drift)
30
+ tests/
31
+ index.test.js node:test
32
+ ```
33
+
34
+ ## What's inside
35
+
36
+ `src/index.js` ships one example helper — `counter(initial)` — to show the
37
+ pattern: a factory that returns reader methods plus the raw reactive cell.
38
+ **Replace it with your own.** Keep the package small and single-purpose; depend
39
+ only on `@zoijs/core`.
40
+
41
+ ## Publishing
42
+
43
+ ```bash
44
+ npm publish --access public
45
+ ```
46
+
47
+ Add a `LICENSE`, fill in the `description`/`keywords` in `package.json`, and you're
48
+ done. Learn more at [zoijs.dev](https://zoijs.dev).
@@ -0,0 +1 @@
1
+ node_modules
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "{{APP_NAME}}",
3
+ "version": "0.1.0",
4
+ "description": "A small library built on @zoijs/core.",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "types": "src/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./src/index.d.ts",
11
+ "default": "./src/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "src",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "sideEffects": false,
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "scripts": {
24
+ "test": "node --test",
25
+ "test:types": "tsc --noEmit -p tsconfig.json"
26
+ },
27
+ "keywords": [
28
+ "zoijs"
29
+ ],
30
+ "license": "MIT",
31
+ "peerDependencies": {
32
+ "@zoijs/core": "^1.2.0"
33
+ },
34
+ "devDependencies": {
35
+ "@zoijs/core": "^1.2.0",
36
+ "typescript": "^5.9.3"
37
+ }
38
+ }
@@ -0,0 +1,24 @@
1
+ // Type definitions for {{APP_NAME}}.
2
+ //
3
+ // Authored in plain JavaScript; these declarations add editor autocomplete and
4
+ // optional type-checking without requiring TypeScript. Core types are imported
5
+ // from @zoijs/core so shapes never drift.
6
+
7
+ import type { State } from "@zoijs/core";
8
+
9
+ /** A reactive counter created by {@link counter}. */
10
+ export interface Counter {
11
+ /** The current value (reactive inside a binding). */
12
+ value(): number;
13
+ /** Add `by` (default 1). */
14
+ increment(by?: number): void;
15
+ /** Subtract `by` (default 1). */
16
+ decrement(by?: number): void;
17
+ /** Reset to the initial value. */
18
+ reset(): void;
19
+ /** The underlying reactive cell — advanced / direct access. */
20
+ state: State<number>;
21
+ }
22
+
23
+ /** Create a reactive counter built on `@zoijs/core`. */
24
+ export function counter(initial?: number): Counter;
@@ -0,0 +1,30 @@
1
+ // {{APP_NAME}} — a small library built on @zoijs/core.
2
+ //
3
+ // Optional Zoijs packages are tiny and import ONLY the core's public API — never
4
+ // each other's internals. This example helper does the same; replace it with your
5
+ // own. Run `npm test` (behavior) and `npm run test:types` (the .d.ts) as you go.
6
+
7
+ import { createState } from "@zoijs/core";
8
+
9
+ /**
10
+ * A reactive counter built on `createState`. A small, illustrative helper showing
11
+ * the shape an optional package takes: a factory that returns reader methods plus
12
+ * the raw reactive cell for advanced use.
13
+ *
14
+ * @param {number} [initial]
15
+ */
16
+ export function counter(initial = 0) {
17
+ const state = createState(initial);
18
+ return {
19
+ /** The current value (reactive inside a binding). */
20
+ value: () => state.get(),
21
+ /** Add `by` (default 1). */
22
+ increment: (by = 1) => state.set(state.get() + by),
23
+ /** Subtract `by` (default 1). */
24
+ decrement: (by = 1) => state.set(state.get() - by),
25
+ /** Reset to the initial value. */
26
+ reset: () => state.set(initial),
27
+ /** The underlying reactive cell — advanced / direct access. */
28
+ state,
29
+ };
30
+ }
@@ -0,0 +1,29 @@
1
+ // Tests for {{APP_NAME}}. Pure logic — no DOM needed. Run with `npm test`.
2
+
3
+ import test from "node:test";
4
+ import assert from "node:assert/strict";
5
+ import { counter } from "../src/index.js";
6
+
7
+ test("counts up and down", () => {
8
+ const c = counter(0);
9
+ assert.equal(c.value(), 0);
10
+ c.increment();
11
+ assert.equal(c.value(), 1);
12
+ c.increment(5);
13
+ assert.equal(c.value(), 6);
14
+ c.decrement(2);
15
+ assert.equal(c.value(), 4);
16
+ });
17
+
18
+ test("reset restores the initial value", () => {
19
+ const c = counter(10);
20
+ c.increment();
21
+ c.reset();
22
+ assert.equal(c.value(), 10);
23
+ });
24
+
25
+ test("exposes the raw reactive cell", () => {
26
+ const c = counter(3);
27
+ assert.equal(typeof c.state.get, "function");
28
+ assert.equal(c.state.peek(), 3);
29
+ });
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "noEmit": true,
4
+ "checkJs": true,
5
+ "strict": true,
6
+ "target": "ES2020",
7
+ "module": "ESNext",
8
+ "moduleResolution": "bundler",
9
+ "lib": ["ES2020", "DOM"],
10
+ "skipLibCheck": true,
11
+ "types": []
12
+ },
13
+ "include": ["src/**/*"]
14
+ }
@@ -0,0 +1,34 @@
1
+ # {{APP_TITLE}}
2
+
3
+ The smallest possible [Zoijs](https://zoijs.dev) app — **two files, no install, no
4
+ build step.** A blank canvas.
5
+
6
+ ## Run it
7
+
8
+ Any static file server works. The simplest:
9
+
10
+ ```bash
11
+ npx serve . -l 7310
12
+ ```
13
+
14
+ Then open <http://localhost:7310>.
15
+
16
+ ## What's here
17
+
18
+ - `index.html` — loads `@zoijs/core` from a CDN (pinned to the `v1` major) and
19
+ mounts `app.js`.
20
+ - `app.js` — a counter: state, markup, and one `mount` call.
21
+
22
+ That's the whole project. Edit `app.js` and reload — there is nothing to build.
23
+
24
+ ## Growing up
25
+
26
+ When you want local packages instead of the CDN, or a few components to organize,
27
+ scaffold a fuller starter:
28
+
29
+ ```bash
30
+ npm create zoijs@latest my-app # the app dashboard
31
+ npm create zoijs@latest my-app --template basic # a basic counter
32
+ ```
33
+
34
+ Learn more at [zoijs.dev](https://zoijs.dev).
@@ -0,0 +1,18 @@
1
+ import { html, mount, createState } from "@zoijs/core";
2
+
3
+ // A complete Zoijs app in one file. No install, no build step.
4
+ function App() {
5
+ const count = createState(0);
6
+
7
+ return html`
8
+ <main>
9
+ <h1>{{APP_TITLE}}</h1>
10
+ <p>Edit <code>app.js</code> and reload.</p>
11
+ <button onclick=${() => count.set(count.get() + 1)}>
12
+ Clicked ${() => count.get()} times
13
+ </button>
14
+ </main>
15
+ `;
16
+ }
17
+
18
+ mount(App, "#app");
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>{{APP_TITLE}}</title>
7
+ <!-- Zero install, zero build: load @zoijs/core straight from a CDN.
8
+ Pin the major version (@1) so your app never breaks unexpectedly. -->
9
+ <script type="importmap">
10
+ { "imports": { "@zoijs/core": "https://esm.sh/@zoijs/core@1" } }
11
+ </script>
12
+ </head>
13
+ <body>
14
+ <div id="app"></div>
15
+ <script type="module" src="./app.js"></script>
16
+ </body>
17
+ </html>
@@ -0,0 +1,57 @@
1
+ # {{APP_TITLE}}
2
+
3
+ A [Zoijs](https://zoijs.dev) app with **TypeScript-grade safety and no build step.**
4
+
5
+ The source is plain JavaScript the browser runs as-is — but every file starts with
6
+ `// @ts-check`, and together with the type definitions shipped in `@zoijs/core` you
7
+ get full type-checking, autocomplete, and inline errors. There is **no compile
8
+ step**: you never turn `.ts` into `.js`, because there's no `.ts` to begin with.
9
+
10
+ ## Develop
11
+
12
+ ```bash
13
+ npm install
14
+ npm run dev
15
+ ```
16
+
17
+ ```text
18
+ Zoijs dev server
19
+
20
+ - Local: http://localhost:7310
21
+ ```
22
+
23
+ Open the printed URL (it falls back to 7311–7313 if the port is busy).
24
+
25
+ ## Type-check
26
+
27
+ ```bash
28
+ npm run typecheck
29
+ ```
30
+
31
+ Runs `tsc --noEmit` against `src/**/*.js` using `@zoijs/core`'s types — no output
32
+ files, just type errors if any. Wire it into CI or your editor.
33
+
34
+ ## How the typing works
35
+
36
+ - `// @ts-check` at the top of a file turns on type-checking for that file.
37
+ - `@typedef` / `@type` JSDoc comments add your own types (see `src/app.js`).
38
+ - `@zoijs/core` ships `.d.ts`, so `createState`, `html`, `each`, etc. are fully
39
+ typed — e.g. `createState<Todo[]>(…)` gives you a typed list.
40
+
41
+ Prefer authoring real `.ts`? You can, but it would require adding a `tsc` compile
42
+ step — the one thing Zoijs avoids. This template keeps the no-build promise.
43
+
44
+ ## Project layout
45
+
46
+ ```
47
+ {{APP_NAME}}/
48
+ index.html import map + #app mount point
49
+ tsconfig.json strict, checkJs, noEmit (type-check only)
50
+ dev-server.mjs tiny zero-dependency static server (npm run dev)
51
+ src/
52
+ app.js your app, typed with @ts-check
53
+ style.css plain CSS
54
+ ```
55
+
56
+ No bundler, no build step. Open the files and read them. Learn more at
57
+ [zoijs.dev](https://zoijs.dev).
@@ -0,0 +1 @@
1
+ node_modules
@@ -0,0 +1,74 @@
1
+ // dev-server.mjs — a tiny static file server for this Zoijs app.
2
+ //
3
+ // Zero dependencies (Node built-ins only), no build step, no bundler. It serves
4
+ // the project files so the import map in index.html can load @zoijs/core from
5
+ // node_modules. Tries port 7310, then 7311 / 7312 / 7313 if one is busy.
6
+ //
7
+ // node dev-server.mjs (this is what `npm run dev` runs)
8
+
9
+ import { createServer } from "node:http";
10
+ import { readFile } from "node:fs/promises";
11
+ import { extname, join, normalize } from "node:path";
12
+
13
+ const PORTS = [7310, 7311, 7312, 7313];
14
+ const ROOT = process.cwd();
15
+
16
+ const TYPES = {
17
+ ".html": "text/html; charset=utf-8",
18
+ ".js": "text/javascript; charset=utf-8",
19
+ ".mjs": "text/javascript; charset=utf-8",
20
+ ".css": "text/css; charset=utf-8",
21
+ ".json": "application/json; charset=utf-8",
22
+ ".svg": "image/svg+xml",
23
+ ".ico": "image/x-icon",
24
+ ".png": "image/png",
25
+ ".woff2": "font/woff2",
26
+ };
27
+
28
+ const server = createServer(async (req, res) => {
29
+ let pathname = decodeURIComponent(new URL(req.url, "http://localhost").pathname);
30
+ if (pathname === "/") pathname = "/index.html";
31
+
32
+ // Resolve inside ROOT and refuse anything that climbs out of it.
33
+ const filePath = join(ROOT, normalize(pathname));
34
+ if (!filePath.startsWith(ROOT)) {
35
+ res.writeHead(403).end("Forbidden");
36
+ return;
37
+ }
38
+ try {
39
+ const body = await readFile(filePath);
40
+ res.writeHead(200, { "Content-Type": TYPES[extname(filePath)] || "application/octet-stream" });
41
+ res.end(body);
42
+ } catch {
43
+ res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" }).end("Not found");
44
+ }
45
+ });
46
+
47
+ function start(i = 0) {
48
+ if (i >= PORTS.length) {
49
+ console.error(`\nAll dev ports are busy (${PORTS.join(", ")}). Free one and try again.\n`);
50
+ process.exit(1);
51
+ }
52
+ // Paired once-listeners: each attempt removes its sibling so a failed bind
53
+ // can't leave a stale "listening" handler that prints the wrong port later.
54
+ const onError = (err) => {
55
+ server.removeListener("listening", onListening);
56
+ if (err.code === "EADDRINUSE") start(i + 1);
57
+ else {
58
+ console.error(err);
59
+ process.exit(1);
60
+ }
61
+ };
62
+ const onListening = () => {
63
+ server.removeListener("error", onError);
64
+ const lines = ["", " Zoijs dev server", "", ` - Local: http://localhost:${PORTS[i]}`];
65
+ if (i > 0) lines.push(` (ports ${PORTS.slice(0, i).join(", ")} were busy)`);
66
+ lines.push("");
67
+ console.log(lines.join("\n"));
68
+ };
69
+ server.once("error", onError);
70
+ server.once("listening", onListening);
71
+ server.listen(PORTS[i]);
72
+ }
73
+
74
+ start();
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>{{APP_TITLE}}</title>
7
+ <link rel="stylesheet" href="./src/style.css" />
8
+ <!-- No build step: an import map points the @zoijs/core name at the package
9
+ installed in node_modules. `npm install` puts it there. -->
10
+ <script type="importmap">
11
+ {
12
+ "imports": {
13
+ "@zoijs/core": "./node_modules/@zoijs/core/src/index.js"
14
+ }
15
+ }
16
+ </script>
17
+ </head>
18
+ <body>
19
+ <div id="app"></div>
20
+ <script type="module" src="./src/app.js"></script>
21
+ </body>
22
+ </html>
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "{{APP_NAME}}",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "node dev-server.mjs",
8
+ "typecheck": "tsc --noEmit"
9
+ },
10
+ "dependencies": {
11
+ "@zoijs/core": "^1.2.0"
12
+ },
13
+ "devDependencies": {
14
+ "typescript": "^5.9.3"
15
+ }
16
+ }
@@ -0,0 +1,64 @@
1
+ // @ts-check
2
+ // TypeScript-grade safety with NO build step. This is plain JavaScript the
3
+ // browser runs as-is — but `@ts-check` + the shipped `@zoijs/core` types give you
4
+ // full type-checking and autocomplete. Run `npm run typecheck` (tsc --noEmit).
5
+ import { html, mount, createState, each } from "@zoijs/core";
6
+
7
+ /** @typedef {{ id: number; text: string; done: boolean }} Todo */
8
+
9
+ function App() {
10
+ /** @type {import("@zoijs/core").State<Todo[]>} */
11
+ const todos = createState([
12
+ { id: 1, text: "Edit src/app.js", done: false },
13
+ { id: 2, text: "Run npm run typecheck", done: false },
14
+ ]);
15
+ const draft = createState("");
16
+ let nextId = 3;
17
+
18
+ /** @param {Event} e */
19
+ const add = (e) => {
20
+ e.preventDefault();
21
+ const text = draft.get().trim();
22
+ if (!text) return;
23
+ todos.set([...todos.get(), { id: nextId++, text, done: false }]);
24
+ draft.set("");
25
+ };
26
+
27
+ /** @param {number} id */
28
+ const toggle = (id) =>
29
+ todos.set(todos.get().map((t) => (t.id === id ? { ...t, done: !t.done } : t)));
30
+
31
+ return html`
32
+ <main>
33
+ <h1>{{APP_TITLE}}</h1>
34
+ <p>Typed with <code>@ts-check</code> — no build step. Run <code>npm run typecheck</code>.</p>
35
+
36
+ <form onsubmit=${add}>
37
+ <input
38
+ aria-label="New todo"
39
+ placeholder="Add a todo…"
40
+ value=${() => draft.get()}
41
+ oninput=${(/** @type {Event} */ e) =>
42
+ draft.set(/** @type {HTMLInputElement} */ (e.target).value)} />
43
+ <button type="submit">Add</button>
44
+ </form>
45
+
46
+ <ul>
47
+ ${each(
48
+ () => todos.get(),
49
+ (t) => t.id,
50
+ (t) => html`
51
+ <li>
52
+ <label>
53
+ <input type="checkbox" checked=${() => t.done} onchange=${() => toggle(t.id)} />
54
+ ${() => t.text}
55
+ </label>
56
+ </li>
57
+ `
58
+ )}
59
+ </ul>
60
+ </main>
61
+ `;
62
+ }
63
+
64
+ mount(App, "#app");
@@ -0,0 +1,33 @@
1
+ :root {
2
+ color-scheme: light dark;
3
+ font-family: system-ui, sans-serif;
4
+ }
5
+
6
+ body {
7
+ margin: 0;
8
+ display: grid;
9
+ place-items: center;
10
+ min-height: 100vh;
11
+ }
12
+
13
+ main {
14
+ text-align: center;
15
+ padding: 2rem;
16
+ }
17
+
18
+ h1 {
19
+ margin: 0 0 0.5rem;
20
+ }
21
+
22
+ button {
23
+ font: inherit;
24
+ padding: 0.6rem 1.2rem;
25
+ border: 1px solid currentColor;
26
+ border-radius: 8px;
27
+ background: transparent;
28
+ cursor: pointer;
29
+ }
30
+
31
+ button:hover {
32
+ background: rgba(127, 127, 127, 0.12);
33
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "noEmit": true,
4
+ "checkJs": true,
5
+ "allowJs": true,
6
+ "strict": true,
7
+ "target": "ES2020",
8
+ "module": "ESNext",
9
+ "moduleResolution": "bundler",
10
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
11
+ "skipLibCheck": true,
12
+ "types": []
13
+ },
14
+ "include": ["src/**/*.js"]
15
+ }