@goodfellow-cms/next 0.2.0 → 0.3.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/dist/admin.js CHANGED
@@ -4,7 +4,7 @@ import { Admin } from "@goodfellow-cms/admin";
4
4
  import "@puckeditor/core/puck.css";
5
5
  import "@goodfellow-cms/admin/styles.css";
6
6
  //#region src/generated/theme-css.ts
7
- var theme_css_default = "/*\n * Maps the site theme (CSS variables written from content/site.json) onto\n * Tailwind, so classes like bg-primary, text-muted-foreground, font-heading and\n * rounded-lg follow the theme. Import after \"tailwindcss\".\n */\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-border: var(--border);\n /* The rest of shadcn/ui's colors, for blocks built with it, follow the ones above unless custom CSS sets them. */\n --color-card: var(--card, var(--background));\n --color-card-foreground: var(--card-foreground, var(--foreground));\n --color-popover: var(--popover, var(--background));\n --color-popover-foreground: var(--popover-foreground, var(--foreground));\n --color-destructive: var(--destructive, #dc2626);\n --color-input: var(--input, var(--border));\n --color-ring: var(--ring, var(--primary));\n --font-sans: var(--gf-font-body);\n --font-heading: var(--gf-font-heading);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n}\n\n@layer base {\n *,\n ::before,\n ::after {\n border-color: var(--color-border);\n }\n\n body {\n background-color: var(--color-background);\n color: var(--color-foreground);\n /* Keeps the footer at the bottom of short pages. */\n display: flex;\n flex-direction: column;\n min-height: 100dvh;\n }\n\n .gf-main {\n flex: 1;\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: var(--font-heading);\n }\n}\n";
7
+ var theme_css_default = "/*\n * Maps the site theme (CSS variables written from content/site.json) onto\n * Tailwind, so classes like bg-primary, text-muted-foreground, font-heading and\n * rounded-lg follow the theme. Import after \"tailwindcss\".\n */\n/*\n * Blocks' dark: classes apply only where the site has dark mode\n * (Site Settings), which gives its pages <meta name=\"color-scheme\"\n * content=\"light dark\">: when the visitor's computer is set to dark, or when\n * the admin panel's preview shows the site dark. Light-only sites never\n * use them, even on a computer set to dark.\n */\n@custom-variant dark {\n @media (prefers-color-scheme: dark) {\n &:where(\n :root:has(meta[name=\"color-scheme\"][content~=\"dark\"]):not([data-gf-color-scheme=\"light\"]),\n :root:has(meta[name=\"color-scheme\"][content~=\"dark\"]):not([data-gf-color-scheme=\"light\"]) *\n ) {\n @slot;\n }\n }\n &:where([data-gf-color-scheme=\"dark\"], [data-gf-color-scheme=\"dark\"] *) {\n @slot;\n }\n}\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-border: var(--border);\n /* The rest of shadcn/ui's colors, for blocks built with it, follow the ones above unless custom CSS sets them. */\n --color-card: var(--card, var(--background));\n --color-card-foreground: var(--card-foreground, var(--foreground));\n --color-popover: var(--popover, var(--background));\n --color-popover-foreground: var(--popover-foreground, var(--foreground));\n --color-destructive: var(--destructive, #dc2626);\n --color-input: var(--input, var(--border));\n --color-ring: var(--ring, var(--primary));\n --font-sans: var(--gf-font-body);\n --font-heading: var(--gf-font-heading);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n}\n\n@layer base {\n *,\n ::before,\n ::after {\n border-color: var(--color-border);\n }\n\n body {\n background-color: var(--color-background);\n color: var(--color-foreground);\n /* Keeps the footer at the bottom of short pages. */\n display: flex;\n flex-direction: column;\n min-height: 100dvh;\n }\n\n .gf-main {\n flex: 1;\n }\n\n /* The credits of the photos on a page, which their licenses ask for. */\n .gf-credits {\n max-width: 72rem;\n margin: 0 auto;\n padding: 1.5rem 1rem;\n font-size: 0.75rem;\n line-height: 1.5;\n color: var(--color-muted-foreground);\n }\n\n .gf-credits a {\n text-decoration: underline;\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: var(--font-heading);\n }\n}\n";
8
8
  //#endregion
9
9
  //#region src/admin.tsx
10
10
  /**
package/dist/index.d.ts CHANGED
@@ -62,6 +62,11 @@ export declare function goodfellowPages(config: GoodfellowConfig, options?: Good
62
62
  * so other sites get an empty file.
63
63
  */
64
64
  demoContent(): Promise<Response>;
65
+ /**
66
+ * For `app/goodfellow-site.json/route.ts`: what the site says about its blocks, for tools that
67
+ * edit its content without its code, such as the Claude connector.
68
+ */
69
+ siteDescription(): Response;
65
70
  /** For `app/robots.ts`: lets search engines in, and points them at the sitemap once the site's address is set. */
66
71
  robots(): Promise<MetadataRoute.Robots>;
67
72
  };
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { CurrentMenuLinks, NextImage, NextLink } from "./components.js";
2
- import { absoluteUrl, demoContent, findRedirect, getPageHead, googleFontsUrl, loadSiteContent, normalizePagePath, sitePages, themeToCss, todayIn, withBase } from "@goodfellow-cms/core";
3
- import { fileSystemSource, readMediaSizes } from "@goodfellow-cms/core/node";
4
- import { BodyCode, HeadCode, PageBody, PageContent, PageFooter, PageHeader, applyPageEntry, createPuckConfigs, prepareLayout, preparePage } from "@goodfellow-cms/react";
2
+ import { absoluteUrl, colorSchemeMeta, colorSchemeScript, demoContent, findRedirect, fontPreloads, getPageHead, googleFontsUrl, loadSiteContent, normalizePagePath, sitePages, themeToCss, todayIn, withBase } from "@goodfellow-cms/core";
3
+ import { fileSystemSource, fontStandIns, readMediaSizes, readStylesheet } from "@goodfellow-cms/core/node";
4
+ import { BodyCode, HeadCode, PageBody, PageContent, PageFooter, PageHeader, applyPageEntry, createPuckConfigs, describeSite, prepareLayout, preparePage } from "@goodfellow-cms/react";
5
5
  import { notFound, redirect } from "next/navigation";
6
6
  import { cache } from "react";
7
+ import { preload } from "react-dom";
7
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
9
  //#region src/index.tsx
9
10
  /** Next.js's own link and image components, for blocks' `<SiteLink>` and `<SiteImage>`. */
@@ -77,28 +78,44 @@ function goodfellowPages(config, options = {}) {
77
78
  media: await readMediaSizes(root)
78
79
  });
79
80
  /** The site's theme and fonts, which React moves into the document's head. themeToCss escapes its output. */
80
- function Theme({ content }) {
81
+ async function Theme({ content }) {
81
82
  const fontsUrl = googleFontsUrl(content.settings.theme);
82
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("style", {
83
- href: "goodfellow-theme",
84
- precedence: "default",
85
- children: themeToCss(content.settings.theme)
86
- }), fontsUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
87
- /* @__PURE__ */ jsx("link", {
88
- rel: "preconnect",
89
- href: "https://fonts.googleapis.com"
83
+ const [fontFiles, standIns] = await Promise.all([fontPreloads(content.settings.theme, readStylesheet), fontStandIns(content.settings.theme)]);
84
+ for (const href of fontFiles) preload(href, {
85
+ as: "font",
86
+ type: "font/woff2",
87
+ crossOrigin: ""
88
+ });
89
+ const colorScheme = colorSchemeMeta(content.settings.theme);
90
+ const schemeScript = colorSchemeScript(content.settings.theme);
91
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
92
+ colorScheme && /* @__PURE__ */ jsx("meta", {
93
+ name: "color-scheme",
94
+ content: colorScheme
90
95
  }),
91
- /* @__PURE__ */ jsx("link", {
92
- rel: "preconnect",
93
- href: "https://fonts.gstatic.com",
94
- crossOrigin: ""
96
+ schemeScript && /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: schemeScript } }),
97
+ /* @__PURE__ */ jsx("style", {
98
+ href: "goodfellow-theme",
99
+ precedence: "default",
100
+ children: themeToCss(content.settings.theme, standIns)
95
101
  }),
96
- /* @__PURE__ */ jsx("link", {
97
- rel: "stylesheet",
98
- href: fontsUrl,
99
- precedence: "default"
100
- })
101
- ] })] });
102
+ fontsUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
103
+ /* @__PURE__ */ jsx("link", {
104
+ rel: "preconnect",
105
+ href: "https://fonts.googleapis.com"
106
+ }),
107
+ /* @__PURE__ */ jsx("link", {
108
+ rel: "preconnect",
109
+ href: "https://fonts.gstatic.com",
110
+ crossOrigin: ""
111
+ }),
112
+ /* @__PURE__ */ jsx("link", {
113
+ rel: "stylesheet",
114
+ href: fontsUrl,
115
+ precedence: "default"
116
+ })
117
+ ] })
118
+ ] });
102
119
  }
103
120
  return {
104
121
  /** Every page's address, so Next.js builds them all. Any other address is "not found". */
@@ -201,6 +218,13 @@ function goodfellowPages(config, options = {}) {
201
218
  if (!config.demo) return new Response(null, { status: 404 });
202
219
  return new Response(await demoContent(fileSystemSource(root)), { headers: { "content-type": "application/json" } });
203
220
  },
221
+ /**
222
+ * For `app/goodfellow-site.json/route.ts`: what the site says about its blocks, for tools that
223
+ * edit its content without its code, such as the Claude connector.
224
+ */
225
+ siteDescription() {
226
+ return Response.json(describeSite(config));
227
+ },
204
228
  /** For `app/robots.ts`: lets search engines in, and points them at the sitemap once the site's address is set. */
205
229
  async robots() {
206
230
  const url = (await site()).settings.url;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodfellow-cms/next",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Goodfellow pages and the admin panel in a Next.js site.",
5
5
  "keywords": [
6
6
  "goodfellow",
@@ -53,15 +53,15 @@
53
53
  "dist"
54
54
  ],
55
55
  "dependencies": {
56
- "@goodfellow-cms/core": "0.2.0",
57
- "@goodfellow-cms/react": "0.2.0"
56
+ "@goodfellow-cms/core": "0.3.0",
57
+ "@goodfellow-cms/react": "0.3.0"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@puckeditor/core": "0.23.0",
61
61
  "next": "^16.0.0",
62
62
  "react": "^19.0.0",
63
63
  "react-dom": "^19.0.0",
64
- "@goodfellow-cms/admin": "0.2.0"
64
+ "@goodfellow-cms/admin": "0.3.0"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@puckeditor/core": "0.23.0",
@@ -71,7 +71,7 @@
71
71
  "next": "16.3.8",
72
72
  "react": "19.3.0",
73
73
  "react-dom": "19.3.0",
74
- "@goodfellow-cms/admin": "0.2.0"
74
+ "@goodfellow-cms/admin": "0.3.0"
75
75
  },
76
76
  "engines": {
77
77
  "node": ">=22"