@monospaced/create-set 0.22.0 → 0.23.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.
- package/README.md +3 -1
- package/package.json +4 -4
- package/src/cli.mjs +20 -2
- package/src/constants.mjs +3 -0
- package/src/page.mjs +3 -9
- package/src/plan.mjs +5 -4
- package/src/templates.mjs +36 -17
- package/src/toolchain.mjs +9 -9
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Project scaffolding for Set. Bootstraps a site or app with Set's components, too
|
|
|
6
6
|
pnpm create @monospaced/set my-site
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Prompts for a package name, site title, description
|
|
9
|
+
Prompts for a package name, site title, description, variant (`html`, `prerender` or `react`) and brand (`mnsp` or `wrfr`), each showing its default, which Enter accepts. Each has a flag (`--name`, `--title`, `--description`, `--variant`, `--brand`), and `--defaults` takes every default without prompting, so it runs non-interactively too; without a terminal, anything unanswered is refused rather than guessed. Refuses a directory that isn't empty.
|
|
10
10
|
|
|
11
11
|
## Variants
|
|
12
12
|
|
|
@@ -18,6 +18,8 @@ Three ways to author, sharing everything else.
|
|
|
18
18
|
|
|
19
19
|
In `html` and `prerender`, a page is a folder with an `index.html` and its path is its URL; Vite discovers them, so adding a page is adding a folder.
|
|
20
20
|
|
|
21
|
+
The brand picks which of core's stylesheets the project imports (`styles/mnsp.css` or `styles/wrfr.css`, one brand each) and the `brand` on `Root`.
|
|
22
|
+
|
|
21
23
|
## What you get
|
|
22
24
|
|
|
23
25
|
A Vite and TypeScript project with a starter page built from Set components, a `src/styles.css` for your own styles, Set's ESLint and Stylelint presets, Prettier, Husky and lint-staged, VS Code settings, and Lightning CSS targets from Set's Baseline query.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monospaced/create-set",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Project scaffolding for Set. Bootstraps a site or app with Set's components, tooling and defaults.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@clack/prompts": "^1.8.1",
|
|
21
|
-
"@monospaced/set-core": "0.
|
|
21
|
+
"@monospaced/set-core": "0.23.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"prettier": "^3.
|
|
25
|
-
"vitest": "^
|
|
24
|
+
"prettier": "^3.9.10",
|
|
25
|
+
"vitest": "^5.1.0"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"sync": "node scripts/sync.mjs",
|
package/src/cli.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
toTitle,
|
|
10
10
|
validatePackageName,
|
|
11
11
|
} from "./answers.mjs";
|
|
12
|
-
import { VARIANTS } from "./constants.mjs";
|
|
12
|
+
import { BRANDS, VARIANTS } from "./constants.mjs";
|
|
13
13
|
import { execute, isEmptyDirectory } from "./execute.mjs";
|
|
14
14
|
|
|
15
15
|
const { version } = createRequire(import.meta.url)("../package.json");
|
|
@@ -26,12 +26,14 @@ Options:
|
|
|
26
26
|
--variant <variant> html: pages are HTML you write (default)
|
|
27
27
|
prerender: pages are render functions, built to HTML
|
|
28
28
|
react: an app rendered by React
|
|
29
|
+
--brand <brand> mnsp: Monospaced (default); wrfr: wireframe
|
|
29
30
|
--defaults Take every default without prompting
|
|
30
31
|
-h, --help Show this help
|
|
31
32
|
-v, --version Show the version
|
|
32
33
|
`;
|
|
33
34
|
|
|
34
35
|
const OPTIONS = {
|
|
36
|
+
brand: { type: "string" },
|
|
35
37
|
defaults: { type: "boolean" },
|
|
36
38
|
description: { type: "string" },
|
|
37
39
|
help: { short: "h", type: "boolean" },
|
|
@@ -51,6 +53,11 @@ const VARIANT_OPTIONS = [
|
|
|
51
53
|
{ hint: "an app rendered by React", label: "React", value: "react" },
|
|
52
54
|
];
|
|
53
55
|
|
|
56
|
+
const BRAND_OPTIONS = [
|
|
57
|
+
{ label: "Monospaced", value: "mnsp" },
|
|
58
|
+
{ hint: "greyscale, for prototypes", label: "Wireframe", value: "wrfr" },
|
|
59
|
+
];
|
|
60
|
+
|
|
54
61
|
/** Prompts, or returns `undefined` when the user cancels. */
|
|
55
62
|
async function prompt(promise) {
|
|
56
63
|
const value = await promise;
|
|
@@ -129,7 +136,18 @@ async function ask(values, positional) {
|
|
|
129
136
|
return;
|
|
130
137
|
}
|
|
131
138
|
|
|
132
|
-
|
|
139
|
+
const brand = await answer(values, "brand", BRANDS[0], {
|
|
140
|
+
message: "Brand",
|
|
141
|
+
options: BRAND_OPTIONS,
|
|
142
|
+
});
|
|
143
|
+
if (brand === undefined) return;
|
|
144
|
+
|
|
145
|
+
if (!BRANDS.includes(brand)) {
|
|
146
|
+
p.cancel(`${brand} is not a brand. Use ${BRANDS.join(" or ")}.`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { brand, description, dir, name, title, variant };
|
|
133
151
|
}
|
|
134
152
|
|
|
135
153
|
export async function run(argv) {
|
package/src/constants.mjs
CHANGED
|
@@ -5,6 +5,9 @@ export const OG_IMAGE =
|
|
|
5
5
|
/** How pages are authored. The first is the default. */
|
|
6
6
|
export const VARIANTS = ["html", "prerender", "react"];
|
|
7
7
|
|
|
8
|
+
/** Set brands. The first is the default. */
|
|
9
|
+
export const BRANDS = ["mnsp", "wrfr"];
|
|
10
|
+
|
|
8
11
|
/** Installed live at generation time, so nothing in the template goes stale. */
|
|
9
12
|
export const RUNTIME_DEPENDENCIES = [
|
|
10
13
|
"@monospaced/set-assets",
|
package/src/page.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
escapeHtml,
|
|
2
3
|
renderSetBox,
|
|
3
4
|
renderSetContainer,
|
|
4
5
|
renderSetHeading,
|
|
@@ -11,14 +12,6 @@ import {
|
|
|
11
12
|
SET_LIGHTSWITCH_STORAGE_KEY,
|
|
12
13
|
} from "@monospaced/set-core";
|
|
13
14
|
|
|
14
|
-
/** Escapes a value for an HTML attribute or text node. */
|
|
15
|
-
export const escapeHtml = (value) =>
|
|
16
|
-
value
|
|
17
|
-
.replaceAll("&", "&")
|
|
18
|
-
.replaceAll("<", "<")
|
|
19
|
-
.replaceAll(">", ">")
|
|
20
|
-
.replaceAll('"', """);
|
|
21
|
-
|
|
22
15
|
/*
|
|
23
16
|
* Stamps a stored lightswitch override onto the root before its content
|
|
24
17
|
* parses, so an overridden theme paints correctly on first load. Must be the
|
|
@@ -34,7 +27,7 @@ export const themeBootstrap = `<script>try{var t=localStorage.getItem(${JSON.str
|
|
|
34
27
|
* generation time. The `prerender` variant writes the same composition as
|
|
35
28
|
* `src/document.ts` and `src/pages/index.ts`.
|
|
36
29
|
*/
|
|
37
|
-
export function renderHelloPage({ editHint, title }) {
|
|
30
|
+
export function renderHelloPage({ brand, editHint, title }) {
|
|
38
31
|
const header = renderSetContainer({
|
|
39
32
|
maxInlineSize: "none",
|
|
40
33
|
children: renderSetBox({
|
|
@@ -87,6 +80,7 @@ export function renderHelloPage({ editHint, title }) {
|
|
|
87
80
|
return renderSetRoot({
|
|
88
81
|
appOverscrollBehavior: "none",
|
|
89
82
|
appRoot: true,
|
|
83
|
+
brand,
|
|
90
84
|
children: themeBootstrap + page,
|
|
91
85
|
});
|
|
92
86
|
}
|
package/src/plan.mjs
CHANGED
|
@@ -6,7 +6,8 @@ import { NODE_MAJOR, PNPM_VERSION } from "./toolchain.mjs";
|
|
|
6
6
|
* @property {string} name Package name.
|
|
7
7
|
* @property {string} title Site title.
|
|
8
8
|
* @property {string} description Site description.
|
|
9
|
-
* @property {"html" | "prerender"} variant How pages are authored.
|
|
9
|
+
* @property {"html" | "prerender" | "react"} variant How pages are authored.
|
|
10
|
+
* @property {"mnsp" | "wrfr"} brand Set brand.
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -49,12 +50,12 @@ export function plan(answers) {
|
|
|
49
50
|
const variants = {
|
|
50
51
|
html: {
|
|
51
52
|
"index.html": templates.indexHtml(context),
|
|
52
|
-
"src/main.ts": templates.mainTs(),
|
|
53
|
+
"src/main.ts": templates.mainTs(context),
|
|
53
54
|
},
|
|
54
55
|
prerender: {
|
|
55
56
|
"index.html": templates.routeStub(),
|
|
56
57
|
"src/document.ts": templates.documentTs(),
|
|
57
|
-
"src/main.ts": templates.mainTs(),
|
|
58
|
+
"src/main.ts": templates.mainTs(context),
|
|
58
59
|
"src/pages.ts": templates.pagesTs(),
|
|
59
60
|
"src/pages/index.ts": templates.indexPageTs(),
|
|
60
61
|
"src/site.ts": templates.siteTs(context),
|
|
@@ -62,7 +63,7 @@ export function plan(answers) {
|
|
|
62
63
|
react: {
|
|
63
64
|
"index.html": templates.indexHtml(context),
|
|
64
65
|
"src/App.tsx": templates.appTsx(context),
|
|
65
|
-
"src/main.tsx": templates.mainTsx(),
|
|
66
|
+
"src/main.tsx": templates.mainTsx(context),
|
|
66
67
|
},
|
|
67
68
|
};
|
|
68
69
|
const variant = variants[answers.variant];
|
package/src/templates.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { escapeHtml } from "@monospaced/set-core";
|
|
2
|
+
|
|
1
3
|
import { OG_IMAGE } from "./constants.mjs";
|
|
2
|
-
import {
|
|
4
|
+
import { renderHelloPage, themeBootstrap } from "./page.mjs";
|
|
3
5
|
|
|
4
6
|
const json = (value) => `${JSON.stringify(value, null, 2)}\n`;
|
|
5
7
|
|
|
@@ -39,7 +41,12 @@ export const packageJson = ({ description, name, nodeMajor, pnpmVersion }) => {
|
|
|
39
41
|
});
|
|
40
42
|
};
|
|
41
43
|
|
|
42
|
-
export const indexHtml = ({
|
|
44
|
+
export const indexHtml = ({
|
|
45
|
+
brand,
|
|
46
|
+
description,
|
|
47
|
+
title,
|
|
48
|
+
variant,
|
|
49
|
+
}) => `<!doctype html>
|
|
43
50
|
<html lang="en">
|
|
44
51
|
<head>
|
|
45
52
|
<meta charset="utf-8" />
|
|
@@ -71,7 +78,7 @@ ${
|
|
|
71
78
|
variant === "react"
|
|
72
79
|
? ` <div id="root"></div>
|
|
73
80
|
<script type="module" src="/src/main.tsx"></script>`
|
|
74
|
-
: ` ${renderHelloPage({ editHint: "index.html", title })}
|
|
81
|
+
: ` ${renderHelloPage({ brand, editHint: "index.html", title })}
|
|
75
82
|
<script type="module" src="/src/main.ts"></script>`
|
|
76
83
|
}
|
|
77
84
|
</body>
|
|
@@ -98,8 +105,8 @@ export const manifest = ({ description, title }) =>
|
|
|
98
105
|
),
|
|
99
106
|
});
|
|
100
107
|
|
|
101
|
-
export const mainTs = () => `import "@monospaced/set-assets/fonts.css";
|
|
102
|
-
import "@monospaced/set-core/styles.css";
|
|
108
|
+
export const mainTs = ({ brand }) => `import "@monospaced/set-assets/fonts.css";
|
|
109
|
+
import "@monospaced/set-core/styles/${brand}.css";
|
|
103
110
|
import "./styles.css";
|
|
104
111
|
|
|
105
112
|
import { defineSetComponents } from "@monospaced/set-core";
|
|
@@ -163,8 +170,10 @@ export default defineConfig({
|
|
|
163
170
|
`;
|
|
164
171
|
};
|
|
165
172
|
|
|
166
|
-
export const mainTsx = (
|
|
167
|
-
|
|
173
|
+
export const mainTsx = ({
|
|
174
|
+
brand,
|
|
175
|
+
}) => `import "@monospaced/set-assets/fonts.css";
|
|
176
|
+
import "@monospaced/set-core/styles/${brand}.css";
|
|
168
177
|
import "./styles.css";
|
|
169
178
|
|
|
170
179
|
import { SET_LIGHTSWITCH_STORAGE_KEY } from "@monospaced/set-core";
|
|
@@ -197,7 +206,7 @@ createRoot(container).render(
|
|
|
197
206
|
);
|
|
198
207
|
`;
|
|
199
208
|
|
|
200
|
-
export const appTsx = ({ title }) => `import {
|
|
209
|
+
export const appTsx = ({ brand, title }) => `import {
|
|
201
210
|
Box,
|
|
202
211
|
Container,
|
|
203
212
|
Heading,
|
|
@@ -211,7 +220,7 @@ export const appTsx = ({ title }) => `import {
|
|
|
211
220
|
|
|
212
221
|
export function App({ theme }: { theme?: "light" | "dark" }) {
|
|
213
222
|
return (
|
|
214
|
-
<Root appOverscrollBehavior="none" appRoot theme={theme}>
|
|
223
|
+
<Root appOverscrollBehavior="none" appRoot brand="${brand}" theme={theme}>
|
|
215
224
|
<Page
|
|
216
225
|
footer={null}
|
|
217
226
|
header={
|
|
@@ -249,7 +258,22 @@ export const routeStub = () => `<!doctype html>
|
|
|
249
258
|
<!-- Route marker. This page is rendered from src/pages.ts by the plugin in vite.config.ts. -->
|
|
250
259
|
`;
|
|
251
260
|
|
|
252
|
-
export const siteTs = ({
|
|
261
|
+
export const siteTs = ({
|
|
262
|
+
brand,
|
|
263
|
+
description,
|
|
264
|
+
title,
|
|
265
|
+
}) => `import type { SetBrand } from "@monospaced/set-core";
|
|
266
|
+
|
|
267
|
+
interface Site {
|
|
268
|
+
brand: SetBrand;
|
|
269
|
+
description: string;
|
|
270
|
+
name: string;
|
|
271
|
+
ogImage: string;
|
|
272
|
+
url: string;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export const site: Site = {
|
|
276
|
+
brand: ${JSON.stringify(brand)},
|
|
253
277
|
name: ${JSON.stringify(title)},
|
|
254
278
|
description: ${JSON.stringify(description)},
|
|
255
279
|
// Set once the site has a domain; canonical and og:url derive from it.
|
|
@@ -259,6 +283,7 @@ export const siteTs = ({ description, title }) => `export const site = {
|
|
|
259
283
|
`;
|
|
260
284
|
|
|
261
285
|
export const documentTs = () => `import {
|
|
286
|
+
escapeHtml,
|
|
262
287
|
renderSetBox,
|
|
263
288
|
renderSetContainer,
|
|
264
289
|
renderSetHeading,
|
|
@@ -279,13 +304,6 @@ export interface Page {
|
|
|
279
304
|
render: () => string | Promise<string>;
|
|
280
305
|
}
|
|
281
306
|
|
|
282
|
-
const escapeHtml = (value: string): string =>
|
|
283
|
-
value
|
|
284
|
-
.replaceAll("&", "&")
|
|
285
|
-
.replaceAll("<", "<")
|
|
286
|
-
.replaceAll(">", ">")
|
|
287
|
-
.replaceAll('"', """);
|
|
288
|
-
|
|
289
307
|
/*
|
|
290
308
|
* Stamps a stored lightswitch override onto the root before its content
|
|
291
309
|
* parses, so an overridden theme paints correctly on first load. Must be the
|
|
@@ -321,6 +339,7 @@ export async function renderDocument(page: Page, route: string): Promise<string>
|
|
|
321
339
|
const body = renderSetRoot({
|
|
322
340
|
appOverscrollBehavior: "none",
|
|
323
341
|
appRoot: true,
|
|
342
|
+
brand: site.brand,
|
|
324
343
|
children:
|
|
325
344
|
themeBootstrap +
|
|
326
345
|
renderSetPage({
|
package/src/toolchain.mjs
CHANGED
|
@@ -10,19 +10,19 @@ export const PNPM_VERSION = "12.17.0";
|
|
|
10
10
|
export const TOOLING = {
|
|
11
11
|
"@types/node": "^26.6.6",
|
|
12
12
|
husky: "^9.1.7",
|
|
13
|
-
"lint-staged": "^17.0
|
|
14
|
-
prettier: "^3.
|
|
15
|
-
vite: "^
|
|
16
|
-
vitest: "^
|
|
13
|
+
"lint-staged": "^17.6.0",
|
|
14
|
+
prettier: "^3.9.10",
|
|
15
|
+
vite: "^8.3.6",
|
|
16
|
+
vitest: "^5.1.0",
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
/** What the React variant adds, at the monorepo's ranges. */
|
|
20
20
|
export const REACT = {
|
|
21
|
-
dependencies: { react: "^19.
|
|
21
|
+
dependencies: { react: "^19.3.1", "react-dom": "^19.3.1" },
|
|
22
22
|
devDependencies: {
|
|
23
|
-
"@types/react": "^19.
|
|
24
|
-
"@types/react-dom": "^19.
|
|
25
|
-
"@vitejs/plugin-react": "^
|
|
26
|
-
jsdom: "^
|
|
23
|
+
"@types/react": "^19.3.0",
|
|
24
|
+
"@types/react-dom": "^19.3.0",
|
|
25
|
+
"@vitejs/plugin-react": "^6.2.1",
|
|
26
|
+
jsdom: "^31.0.0",
|
|
27
27
|
},
|
|
28
28
|
};
|