@bison-lab/payload-core 0.1.0 → 3.8.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 +132 -18
- package/dist/admin.d.mts +28 -0
- package/dist/admin.d.mts.map +1 -0
- package/dist/admin.mjs +433 -0
- package/dist/admin.mjs.map +1 -0
- package/dist/index.d.mts +57 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +189 -1
- package/dist/index.mjs.map +1 -1
- package/dist/metadata.d.mts +1 -1
- package/dist/react.d.mts +32 -0
- package/dist/react.d.mts.map +1 -0
- package/dist/react.mjs +132 -0
- package/dist/react.mjs.map +1 -0
- package/dist/theme.d.mts +38 -0
- package/dist/theme.d.mts.map +1 -0
- package/dist/theme.mjs +39 -0
- package/dist/theme.mjs.map +1 -0
- package/dist/{title-Wut0nzJQ.d.mts → title-B2-gWQZd.d.mts} +1 -1
- package/dist/{title-Wut0nzJQ.d.mts.map → title-B2-gWQZd.d.mts.map} +1 -1
- package/dist/types-DWwL-JEr.mjs +76 -0
- package/dist/types-DWwL-JEr.mjs.map +1 -0
- package/dist/types-pFpmDeSA.d.mts +91 -0
- package/dist/types-pFpmDeSA.d.mts.map +1 -0
- package/package.json +53 -4
package/dist/theme.mjs
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { r as themeConfigFromDoc, t as THEME_SLUG } from "./types-DWwL-JEr.mjs";
|
|
2
|
+
import { fontFaceCss, fontPreloads } from "@bison-lab/fonts";
|
|
3
|
+
import { buildThemeCss, themeFontIds } from "@bison-lab/tokens";
|
|
4
|
+
//#region src/theme/published.ts
|
|
5
|
+
/**
|
|
6
|
+
* The published Theme, or `seed` when nothing has been published. A newer
|
|
7
|
+
* draft never reaches the public site (`draft: false`). Access is
|
|
8
|
+
* overridden so a logged-out request still gets the published colours.
|
|
9
|
+
*/
|
|
10
|
+
async function getPublishedTheme(payload, seed) {
|
|
11
|
+
return themeConfigFromDoc(await payload.findGlobal({
|
|
12
|
+
slug: "theme",
|
|
13
|
+
draft: false,
|
|
14
|
+
depth: 0,
|
|
15
|
+
overrideAccess: true
|
|
16
|
+
}) ?? {}, seed);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/theme/head.ts
|
|
20
|
+
/**
|
|
21
|
+
* `@font-face` plus `buildThemeCss` as one stylesheet, and the preload
|
|
22
|
+
* list for the families the config names. A root layout (and the admin
|
|
23
|
+
* layout, if it should restyle too) renders `css` in a `<style>` and
|
|
24
|
+
* each preload as `<link rel="preload" as="font">`.
|
|
25
|
+
*/
|
|
26
|
+
function themeHead(config, options = {}) {
|
|
27
|
+
const fontsBaseUrl = options.fontsBaseUrl ?? "/fonts";
|
|
28
|
+
const ids = themeFontIds(config);
|
|
29
|
+
const faces = fontFaceCss(ids, fontsBaseUrl);
|
|
30
|
+
const theme = buildThemeCss(config, { attribute: options.attribute });
|
|
31
|
+
return {
|
|
32
|
+
css: faces ? `${faces}\n\n${theme}` : theme,
|
|
33
|
+
preloads: fontPreloads(ids, fontsBaseUrl)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { THEME_SLUG, getPublishedTheme, themeConfigFromDoc, themeHead };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=theme.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.mjs","names":[],"sources":["../src/theme/published.ts","../src/theme/head.ts"],"sourcesContent":["import type { ThemeConfig } from \"@bison-lab/tokens\";\n\nimport { themeConfigFromDoc } from \"./map\";\nimport { THEME_SLUG } from \"./types\";\nimport type { ThemeDoc } from \"./types\";\n\nexport interface ThemePayload {\n findGlobal: (args: {\n slug: string;\n draft?: boolean;\n depth?: number;\n overrideAccess?: boolean;\n }) => Promise<ThemeDoc | null | undefined>;\n}\n\n/**\n * The published Theme, or `seed` when nothing has been published. A newer\n * draft never reaches the public site (`draft: false`). Access is\n * overridden so a logged-out request still gets the published colours.\n */\nexport async function getPublishedTheme(payload: ThemePayload, seed: ThemeConfig): Promise<ThemeConfig> {\n const doc = await payload.findGlobal({\n slug: THEME_SLUG,\n draft: false,\n depth: 0,\n overrideAccess: true,\n });\n return themeConfigFromDoc(doc ?? {}, seed);\n}\n","import { fontFaceCss, fontPreloads } from \"@bison-lab/fonts\";\nimport { buildThemeCss, themeFontIds, type ThemeConfig } from \"@bison-lab/tokens\";\n\nimport type { ThemeHead, ThemeHeadOptions } from \"./types\";\n\n/**\n * `@font-face` plus `buildThemeCss` as one stylesheet, and the preload\n * list for the families the config names. A root layout (and the admin\n * layout, if it should restyle too) renders `css` in a `<style>` and\n * each preload as `<link rel=\"preload\" as=\"font\">`.\n */\nexport function themeHead(config: ThemeConfig, options: ThemeHeadOptions = {}): ThemeHead {\n const fontsBaseUrl = options.fontsBaseUrl ?? \"/fonts\";\n const ids = themeFontIds(config);\n const faces = fontFaceCss(ids, fontsBaseUrl);\n const theme = buildThemeCss(config, { attribute: options.attribute });\n return {\n css: faces ? `${faces}\\n\\n${theme}` : theme,\n preloads: fontPreloads(ids, fontsBaseUrl),\n };\n}\n"],"mappings":";;;;;;;;;AAoBA,eAAsB,kBAAkB,SAAuB,MAAyC;AAOtG,QAAO,mBANK,MAAM,QAAQ,WAAW;EACnC,MAAA;EACA,OAAO;EACP,OAAO;EACP,gBAAgB;EACjB,CAAC,IAC+B,EAAE,EAAE,KAAK;;;;;;;;;;AChB5C,SAAgB,UAAU,QAAqB,UAA4B,EAAE,EAAa;CACxF,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,MAAM,aAAa,OAAO;CAChC,MAAM,QAAQ,YAAY,KAAK,aAAa;CAC5C,MAAM,QAAQ,cAAc,QAAQ,EAAE,WAAW,QAAQ,WAAW,CAAC;AACrE,QAAO;EACL,KAAK,QAAQ,GAAG,MAAM,MAAM,UAAU;EACtC,UAAU,aAAa,KAAK,aAAa;EAC1C"}
|
|
@@ -52,4 +52,4 @@ declare function documentTitle(siteName: string, pageTitle: string): string;
|
|
|
52
52
|
declare function titleTemplate(siteName: string): string;
|
|
53
53
|
//#endregion
|
|
54
54
|
export { SeoImageSize as a, SeoImageDoc as i, titleTemplate as n, SeoImageValue as o, MediaId as r, SeoMeta as s, documentTitle as t };
|
|
55
|
-
//# sourceMappingURL=title-
|
|
55
|
+
//# sourceMappingURL=title-B2-gWQZd.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"title-
|
|
1
|
+
{"version":3,"file":"title-B2-gWQZd.d.mts","names":[],"sources":["../src/seo/types.ts","../src/seo/title.ts"],"mappings":";;KACY,OAAA;;UAGK,YAAA;EACf,GAAA;EACA,KAAA;EACA,MAAA;AAAA;;;;;;;;AAWF;UAAiB,WAAA;EACf,GAAA;EACA,GAAA;EACA,KAAA;EACA,MAAA;EACA,KAAA;IAAA,CAAW,IAAA,WAAe,YAAA;EAAA;AAAA;;KAIhB,aAAA,GAAgB,OAAA,GAAU,WAAA;;AAAtC;;;UAMiB,OAAA;EACf,KAAA;EACA,WAAA;EACA,KAAA,GAAQ,aAAA;EACR,OAAA;AAAA;;;;AApCF;;;;;iBCKgB,aAAA,CAAc,QAAA,UAAkB,SAAA;;;;;iBAQhC,aAAA,CAAc,QAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { isThemeHex } from "@bison-lab/tokens";
|
|
2
|
+
//#region src/theme/fields.ts
|
|
3
|
+
const THEME_COLOR_FIELD = "@bison-lab/payload-core/admin#ColorField";
|
|
4
|
+
const THEME_FONT_FIELD = "@bison-lab/payload-core/admin#FontField";
|
|
5
|
+
const THEME_CONTRAST_REPORT = "@bison-lab/payload-core/admin#ContrastReport";
|
|
6
|
+
function headingSelectValue(heading) {
|
|
7
|
+
return heading ?? "";
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/theme/map.ts
|
|
11
|
+
function pick(value, fallback) {
|
|
12
|
+
return value == null ? fallback : value;
|
|
13
|
+
}
|
|
14
|
+
function headingFromDoc(heading, seed) {
|
|
15
|
+
if (heading === void 0) return seed;
|
|
16
|
+
if (heading === null || heading === "") return null;
|
|
17
|
+
return heading;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Nested Theme document → flat `ThemeConfig`. Null or missing editor
|
|
21
|
+
* fields take the seed; `darkSelector` and `fontWeights` always come from
|
|
22
|
+
* the seed.
|
|
23
|
+
*/
|
|
24
|
+
function themeConfigFromDoc(doc, seed) {
|
|
25
|
+
const brand = doc?.brand;
|
|
26
|
+
return {
|
|
27
|
+
brandPrimary: pick(brand?.primary, seed.brandPrimary),
|
|
28
|
+
brandSecondary: pick(brand?.secondary, seed.brandSecondary),
|
|
29
|
+
brandAccent: pick(brand?.accent, seed.brandAccent),
|
|
30
|
+
brandHighlight: pick(brand?.highlight, seed.brandHighlight),
|
|
31
|
+
brandSuccess: pick(brand?.success, seed.brandSuccess),
|
|
32
|
+
greyScale: pick(doc?.greyScale, seed.greyScale),
|
|
33
|
+
radius: pick(doc?.radius, seed.radius),
|
|
34
|
+
shadow: pick(doc?.shadow, seed.shadow),
|
|
35
|
+
motion: pick(doc?.motion, seed.motion),
|
|
36
|
+
density: pick(doc?.density, seed.density),
|
|
37
|
+
defaultTheme: pick(doc?.defaultTheme, seed.defaultTheme),
|
|
38
|
+
fontBody: pick(doc?.fonts?.body, seed.fontBody),
|
|
39
|
+
fontHeading: headingFromDoc(doc?.fonts?.heading, seed.fontHeading),
|
|
40
|
+
darkSelector: seed.darkSelector,
|
|
41
|
+
fontWeights: seed.fontWeights
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** The document `seedTheme` writes so a fresh Global matches the seed config. */
|
|
45
|
+
function docFromConfig(config) {
|
|
46
|
+
return {
|
|
47
|
+
brand: {
|
|
48
|
+
primary: config.brandPrimary,
|
|
49
|
+
secondary: config.brandSecondary,
|
|
50
|
+
accent: config.brandAccent,
|
|
51
|
+
highlight: config.brandHighlight,
|
|
52
|
+
success: config.brandSuccess
|
|
53
|
+
},
|
|
54
|
+
greyScale: config.greyScale,
|
|
55
|
+
radius: config.radius,
|
|
56
|
+
shadow: config.shadow,
|
|
57
|
+
motion: config.motion,
|
|
58
|
+
density: config.density,
|
|
59
|
+
defaultTheme: config.defaultTheme,
|
|
60
|
+
fonts: {
|
|
61
|
+
body: config.fontBody,
|
|
62
|
+
heading: config.fontHeading
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function validateThemeHex(value) {
|
|
67
|
+
if (!isThemeHex(value)) return "Enter a six-digit hex colour like #1e3a5f";
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/theme/types.ts
|
|
72
|
+
const THEME_SLUG = "theme";
|
|
73
|
+
//#endregion
|
|
74
|
+
export { THEME_COLOR_FIELD as a, headingSelectValue as c, validateThemeHex as i, docFromConfig as n, THEME_CONTRAST_REPORT as o, themeConfigFromDoc as r, THEME_FONT_FIELD as s, THEME_SLUG as t };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=types-DWwL-JEr.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-DWwL-JEr.mjs","names":[],"sources":["../src/theme/fields.ts","../src/theme/map.ts","../src/theme/types.ts"],"sourcesContent":["import type { ThemeConfig } from \"@bison-lab/tokens\";\n\nimport type { EditableTheme } from \"./types\";\n\nexport const THEME_COLOR_FIELD = \"@bison-lab/payload-core/admin#ColorField\";\nexport const THEME_FONT_FIELD = \"@bison-lab/payload-core/admin#FontField\";\nexport const THEME_CONTRAST_REPORT = \"@bison-lab/payload-core/admin#ContrastReport\";\n\n/**\n * Document path for each editable `ThemeConfig` key. Locked with `satisfies`\n * so a new config field without a Theme field (or the reverse) fails at\n * compile time. `darkSelector` and `fontWeights` are seed-only.\n */\nexport const THEME_FIELD_PATHS = {\n brandPrimary: \"brand.primary\",\n brandSecondary: \"brand.secondary\",\n brandAccent: \"brand.accent\",\n brandHighlight: \"brand.highlight\",\n brandSuccess: \"brand.success\",\n greyScale: \"greyScale\",\n defaultTheme: \"defaultTheme\",\n radius: \"radius\",\n shadow: \"shadow\",\n motion: \"motion\",\n density: \"density\",\n fontBody: \"fonts.body\",\n fontHeading: \"fonts.heading\",\n} as const satisfies Record<keyof EditableTheme, string>;\n\nexport type ThemeFieldPath = (typeof THEME_FIELD_PATHS)[keyof typeof THEME_FIELD_PATHS];\n\n/** Empty select value for heading: same family as body. */\nexport const SAME_AS_BODY = \"\";\n\nexport function headingSelectValue(heading: ThemeConfig[\"fontHeading\"]): string {\n return heading ?? SAME_AS_BODY;\n}\n","import { isThemeHex, type ThemeConfig } from \"@bison-lab/tokens\";\n\nimport { SAME_AS_BODY } from \"./fields\";\nimport type { ThemeDoc } from \"./types\";\n\nfunction pick<T>(value: T | null | undefined, fallback: T): T {\n return value == null ? fallback : value;\n}\n\nfunction headingFromDoc(\n heading: string | null | undefined,\n seed: ThemeConfig[\"fontHeading\"],\n): string | null {\n if (heading === undefined) return seed;\n if (heading === null || heading === SAME_AS_BODY) return null;\n return heading;\n}\n\n/**\n * Nested Theme document → flat `ThemeConfig`. Null or missing editor\n * fields take the seed; `darkSelector` and `fontWeights` always come from\n * the seed.\n */\nexport function themeConfigFromDoc(doc: ThemeDoc | null | undefined, seed: ThemeConfig): ThemeConfig {\n const brand = doc?.brand;\n return {\n brandPrimary: pick(brand?.primary, seed.brandPrimary),\n brandSecondary: pick(brand?.secondary, seed.brandSecondary),\n brandAccent: pick(brand?.accent, seed.brandAccent),\n brandHighlight: pick(brand?.highlight, seed.brandHighlight),\n brandSuccess: pick(brand?.success, seed.brandSuccess),\n greyScale: pick(doc?.greyScale, seed.greyScale),\n radius: pick(doc?.radius, seed.radius),\n shadow: pick(doc?.shadow, seed.shadow),\n motion: pick(doc?.motion, seed.motion),\n density: pick(doc?.density, seed.density),\n defaultTheme: pick(doc?.defaultTheme, seed.defaultTheme),\n fontBody: pick(doc?.fonts?.body, seed.fontBody),\n fontHeading: headingFromDoc(doc?.fonts?.heading, seed.fontHeading),\n darkSelector: seed.darkSelector,\n fontWeights: seed.fontWeights,\n };\n}\n\n/** The document `seedTheme` writes so a fresh Global matches the seed config. */\nexport function docFromConfig(config: ThemeConfig): ThemeDoc {\n return {\n brand: {\n primary: config.brandPrimary,\n secondary: config.brandSecondary,\n accent: config.brandAccent,\n highlight: config.brandHighlight,\n success: config.brandSuccess,\n },\n greyScale: config.greyScale,\n radius: config.radius,\n shadow: config.shadow,\n motion: config.motion,\n density: config.density,\n defaultTheme: config.defaultTheme,\n fonts: {\n body: config.fontBody,\n heading: config.fontHeading,\n },\n };\n}\n\nexport function validateThemeHex(value: unknown): true | string {\n if (!isThemeHex(value)) return \"Enter a six-digit hex colour like #1e3a5f\";\n return true;\n}\n","import type { Access } from \"payload\";\nimport type { FontEntry } from \"@bison-lab/fonts\";\nimport type { ThemeConfig } from \"@bison-lab/tokens\";\n\n/**\n * The Theme document a site's generated types will describe. Optional and\n * nullable, no index signature: a generated Global is assignable to this,\n * never the reverse.\n */\nexport interface ThemeDoc {\n brand?: {\n primary?: string | null;\n secondary?: string | null;\n accent?: string | null;\n highlight?: string | null;\n success?: string | null;\n } | null;\n greyScale?: ThemeConfig[\"greyScale\"] | null;\n radius?: ThemeConfig[\"radius\"] | null;\n shadow?: ThemeConfig[\"shadow\"] | null;\n motion?: ThemeConfig[\"motion\"] | null;\n density?: ThemeConfig[\"density\"] | null;\n defaultTheme?: ThemeConfig[\"defaultTheme\"] | null;\n fonts?: {\n body?: string | null;\n heading?: string | null;\n } | null;\n logo?: number | string | ThemeUploadDoc | null;\n logoMark?: number | string | ThemeUploadDoc | null;\n _status?: \"draft\" | \"published\" | null;\n}\n\nexport interface ThemeUploadDoc {\n id?: number | string | null;\n url?: string | null;\n alt?: string | null;\n}\n\n/**\n * What an editor can change. `darkSelector` and `fontWeights` stay on the\n * seed — they mean nothing in the admin — and `themeConfigFromDoc` puts\n * them back.\n */\nexport type EditableTheme = Omit<ThemeConfig, \"darkSelector\" | \"fontWeights\">;\n\nexport interface CreateThemeOptions {\n /**\n * Required, no default. Predicates live in each site's `src/platform`\n * until BIS-43; pass `canManageBrand` as `update` (and typically\n * `isAuthenticated` as `read`). `readVersions` / draft visibility follow\n * `update`, so only a brand manager sees unpublished edits.\n */\n access: { read: Access; update: Access };\n /** The site's `bison.config.json`. Every field's `defaultValue`, and the fallback `getPublishedTheme` returns. */\n seed: ThemeConfig;\n /** Default: the whole catalogue. */\n fonts?: readonly FontEntry[];\n /** Where the site's `serveFont` route answers, for the picker's specimens. Default `\"/fonts\"`. */\n fontsBaseUrl?: string;\n /** Body-text target the contrast report judges against. Default `4.5`. */\n contrastTarget?: number;\n /**\n * Code-owned preview route. When set, `createTheme` wires\n * `admin.livePreview.url` to it and `THEME_PREVIEW_BREAKPOINTS`.\n * Omit it and the pane stays closed — a site that has not built the\n * route does not get an empty iframe.\n */\n previewPath?: string;\n /** Adds `logo` and `logoMark` upload relations when given. */\n logo?: { collection: string };\n /** Fires from `afterChange` on a published save only, not an autosaved draft. */\n onPublish?: (theme: ThemeConfig, doc: ThemeDoc) => void | Promise<void>;\n}\n\nexport interface ThemeHeadOptions {\n fontsBaseUrl?: string;\n attribute?: \"class\" | \"data-theme\";\n}\n\nexport interface ThemeHead {\n css: string;\n preloads: { href: string; type: \"font/woff2\" }[];\n}\n\nexport const THEME_SLUG = \"theme\";\n"],"mappings":";;AAIA,MAAa,oBAAoB;AACjC,MAAa,mBAAmB;AAChC,MAAa,wBAAwB;AA4BrC,SAAgB,mBAAmB,SAA6C;AAC9E,QAAO,WAAA;;;;AC9BT,SAAS,KAAQ,OAA6B,UAAgB;AAC5D,QAAO,SAAS,OAAO,WAAW;;AAGpC,SAAS,eACP,SACA,MACe;AACf,KAAI,YAAY,KAAA,EAAW,QAAO;AAClC,KAAI,YAAY,QAAQ,YAAA,GAA0B,QAAO;AACzD,QAAO;;;;;;;AAQT,SAAgB,mBAAmB,KAAkC,MAAgC;CACnG,MAAM,QAAQ,KAAK;AACnB,QAAO;EACL,cAAc,KAAK,OAAO,SAAS,KAAK,aAAa;EACrD,gBAAgB,KAAK,OAAO,WAAW,KAAK,eAAe;EAC3D,aAAa,KAAK,OAAO,QAAQ,KAAK,YAAY;EAClD,gBAAgB,KAAK,OAAO,WAAW,KAAK,eAAe;EAC3D,cAAc,KAAK,OAAO,SAAS,KAAK,aAAa;EACrD,WAAW,KAAK,KAAK,WAAW,KAAK,UAAU;EAC/C,QAAQ,KAAK,KAAK,QAAQ,KAAK,OAAO;EACtC,QAAQ,KAAK,KAAK,QAAQ,KAAK,OAAO;EACtC,QAAQ,KAAK,KAAK,QAAQ,KAAK,OAAO;EACtC,SAAS,KAAK,KAAK,SAAS,KAAK,QAAQ;EACzC,cAAc,KAAK,KAAK,cAAc,KAAK,aAAa;EACxD,UAAU,KAAK,KAAK,OAAO,MAAM,KAAK,SAAS;EAC/C,aAAa,eAAe,KAAK,OAAO,SAAS,KAAK,YAAY;EAClE,cAAc,KAAK;EACnB,aAAa,KAAK;EACnB;;;AAIH,SAAgB,cAAc,QAA+B;AAC3D,QAAO;EACL,OAAO;GACL,SAAS,OAAO;GAChB,WAAW,OAAO;GAClB,QAAQ,OAAO;GACf,WAAW,OAAO;GAClB,SAAS,OAAO;GACjB;EACD,WAAW,OAAO;EAClB,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,cAAc,OAAO;EACrB,OAAO;GACL,MAAM,OAAO;GACb,SAAS,OAAO;GACjB;EACF;;AAGH,SAAgB,iBAAiB,OAA+B;AAC9D,KAAI,CAAC,WAAW,MAAM,CAAE,QAAO;AAC/B,QAAO;;;;ACeT,MAAa,aAAa"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { FontEntry } from "@bison-lab/fonts";
|
|
2
|
+
import { ThemeConfig } from "@bison-lab/tokens";
|
|
3
|
+
import { Access } from "payload";
|
|
4
|
+
|
|
5
|
+
//#region src/theme/types.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* The Theme document a site's generated types will describe. Optional and
|
|
8
|
+
* nullable, no index signature: a generated Global is assignable to this,
|
|
9
|
+
* never the reverse.
|
|
10
|
+
*/
|
|
11
|
+
interface ThemeDoc {
|
|
12
|
+
brand?: {
|
|
13
|
+
primary?: string | null;
|
|
14
|
+
secondary?: string | null;
|
|
15
|
+
accent?: string | null;
|
|
16
|
+
highlight?: string | null;
|
|
17
|
+
success?: string | null;
|
|
18
|
+
} | null;
|
|
19
|
+
greyScale?: ThemeConfig["greyScale"] | null;
|
|
20
|
+
radius?: ThemeConfig["radius"] | null;
|
|
21
|
+
shadow?: ThemeConfig["shadow"] | null;
|
|
22
|
+
motion?: ThemeConfig["motion"] | null;
|
|
23
|
+
density?: ThemeConfig["density"] | null;
|
|
24
|
+
defaultTheme?: ThemeConfig["defaultTheme"] | null;
|
|
25
|
+
fonts?: {
|
|
26
|
+
body?: string | null;
|
|
27
|
+
heading?: string | null;
|
|
28
|
+
} | null;
|
|
29
|
+
logo?: number | string | ThemeUploadDoc | null;
|
|
30
|
+
logoMark?: number | string | ThemeUploadDoc | null;
|
|
31
|
+
_status?: "draft" | "published" | null;
|
|
32
|
+
}
|
|
33
|
+
interface ThemeUploadDoc {
|
|
34
|
+
id?: number | string | null;
|
|
35
|
+
url?: string | null;
|
|
36
|
+
alt?: string | null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* What an editor can change. `darkSelector` and `fontWeights` stay on the
|
|
40
|
+
* seed — they mean nothing in the admin — and `themeConfigFromDoc` puts
|
|
41
|
+
* them back.
|
|
42
|
+
*/
|
|
43
|
+
type EditableTheme = Omit<ThemeConfig, "darkSelector" | "fontWeights">;
|
|
44
|
+
interface CreateThemeOptions {
|
|
45
|
+
/**
|
|
46
|
+
* Required, no default. Predicates live in each site's `src/platform`
|
|
47
|
+
* until BIS-43; pass `canManageBrand` as `update` (and typically
|
|
48
|
+
* `isAuthenticated` as `read`). `readVersions` / draft visibility follow
|
|
49
|
+
* `update`, so only a brand manager sees unpublished edits.
|
|
50
|
+
*/
|
|
51
|
+
access: {
|
|
52
|
+
read: Access;
|
|
53
|
+
update: Access;
|
|
54
|
+
};
|
|
55
|
+
/** The site's `bison.config.json`. Every field's `defaultValue`, and the fallback `getPublishedTheme` returns. */
|
|
56
|
+
seed: ThemeConfig;
|
|
57
|
+
/** Default: the whole catalogue. */
|
|
58
|
+
fonts?: readonly FontEntry[];
|
|
59
|
+
/** Where the site's `serveFont` route answers, for the picker's specimens. Default `"/fonts"`. */
|
|
60
|
+
fontsBaseUrl?: string;
|
|
61
|
+
/** Body-text target the contrast report judges against. Default `4.5`. */
|
|
62
|
+
contrastTarget?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Code-owned preview route. When set, `createTheme` wires
|
|
65
|
+
* `admin.livePreview.url` to it and `THEME_PREVIEW_BREAKPOINTS`.
|
|
66
|
+
* Omit it and the pane stays closed — a site that has not built the
|
|
67
|
+
* route does not get an empty iframe.
|
|
68
|
+
*/
|
|
69
|
+
previewPath?: string;
|
|
70
|
+
/** Adds `logo` and `logoMark` upload relations when given. */
|
|
71
|
+
logo?: {
|
|
72
|
+
collection: string;
|
|
73
|
+
};
|
|
74
|
+
/** Fires from `afterChange` on a published save only, not an autosaved draft. */
|
|
75
|
+
onPublish?: (theme: ThemeConfig, doc: ThemeDoc) => void | Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
interface ThemeHeadOptions {
|
|
78
|
+
fontsBaseUrl?: string;
|
|
79
|
+
attribute?: "class" | "data-theme";
|
|
80
|
+
}
|
|
81
|
+
interface ThemeHead {
|
|
82
|
+
css: string;
|
|
83
|
+
preloads: {
|
|
84
|
+
href: string;
|
|
85
|
+
type: "font/woff2";
|
|
86
|
+
}[];
|
|
87
|
+
}
|
|
88
|
+
declare const THEME_SLUG = "theme";
|
|
89
|
+
//#endregion
|
|
90
|
+
export { ThemeHead as a, ThemeDoc as i, EditableTheme as n, ThemeHeadOptions as o, THEME_SLUG as r, ThemeUploadDoc as s, CreateThemeOptions as t };
|
|
91
|
+
//# sourceMappingURL=types-pFpmDeSA.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-pFpmDeSA.d.mts","names":[],"sources":["../src/theme/types.ts"],"mappings":";;;;;;;AASA;;;UAAiB,QAAA;EACf,KAAA;IACE,OAAA;IACA,SAAA;IACA,MAAA;IACA,SAAA;IACA,OAAA;EAAA;EAEF,SAAA,GAAY,WAAA;EACZ,MAAA,GAAS,WAAA;EACT,MAAA,GAAS,WAAA;EACT,MAAA,GAAS,WAAA;EACT,OAAA,GAAU,WAAA;EACV,YAAA,GAAe,WAAA;EACf,KAAA;IACE,IAAA;IACA,OAAA;EAAA;EAEF,IAAA,qBAAyB,cAAA;EACzB,QAAA,qBAA6B,cAAA;EAC7B,OAAA;AAAA;AAAA,UAGe,cAAA;EACf,EAAA;EACA,GAAA;EACA,GAAA;AAAA;;;;;;KAQU,aAAA,GAAgB,IAAA,CAAK,WAAA;AAAA,UAEhB,kBAAA;EAjBc;;;;AAI/B;;EAoBE,MAAA;IAAU,IAAA,EAAM,MAAA;IAAQ,MAAA,EAAQ,MAAA;EAAA;EAjBhC;EAmBA,IAAA,EAAM,WAAA;EAnBH;EAqBH,KAAA,YAAiB,SAAA;EAbM;EAevB,YAAA;EAf0B;EAiB1B,cAAA;EAfe;;;;;;EAsBf,WAAA;EAIoB;EAFpB,IAAA;IAAS,UAAA;EAAA;EAEwD;EAAjE,SAAA,IAAa,KAAA,EAAO,WAAA,EAAa,GAAA,EAAK,QAAA,YAAoB,OAAA;AAAA;AAAA,UAG3C,gBAAA;EACf,YAAA;EACA,SAAA;AAAA;AAAA,UAGe,SAAA;EACf,GAAA;EACA,QAAA;IAAY,IAAA;IAAc,IAAA;EAAA;AAAA;AAAA,cAGf,UAAA"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bison-lab/payload-core",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Site-agnostic Payload CMS configuration for Bison Lab sites: the SEO tab
|
|
3
|
+
"version": "3.8.0",
|
|
4
|
+
"description": "Site-agnostic Payload CMS configuration for Bison Lab sites: the SEO tab, the Theme global, and the metadata and theme readers for the pages they describe",
|
|
5
5
|
"homepage": "https://components.bisonlab.ai",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -22,21 +22,70 @@
|
|
|
22
22
|
"./metadata": {
|
|
23
23
|
"import": "./dist/metadata.mjs",
|
|
24
24
|
"types": "./dist/metadata.d.mts"
|
|
25
|
+
},
|
|
26
|
+
"./theme": {
|
|
27
|
+
"import": "./dist/theme.mjs",
|
|
28
|
+
"types": "./dist/theme.d.mts"
|
|
29
|
+
},
|
|
30
|
+
"./admin": {
|
|
31
|
+
"import": "./dist/admin.mjs",
|
|
32
|
+
"types": "./dist/admin.d.mts"
|
|
33
|
+
},
|
|
34
|
+
"./react": {
|
|
35
|
+
"import": "./dist/react.mjs",
|
|
36
|
+
"types": "./dist/react.d.mts"
|
|
25
37
|
}
|
|
26
38
|
},
|
|
27
39
|
"files": [
|
|
28
40
|
"dist"
|
|
29
41
|
],
|
|
30
42
|
"peerDependencies": {
|
|
43
|
+
"@bison-lab/fonts": "^3.0.0",
|
|
44
|
+
"@bison-lab/tokens": "^3.0.0",
|
|
45
|
+
"@bison-lab/ui": "^3.0.0",
|
|
46
|
+
"@payloadcms/live-preview-react": "^3.0.0",
|
|
31
47
|
"@payloadcms/plugin-seo": "^3.0.0",
|
|
32
|
-
"
|
|
48
|
+
"@payloadcms/ui": "^3.0.0",
|
|
49
|
+
"payload": "^3.0.0",
|
|
50
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"@bison-lab/fonts": {
|
|
54
|
+
"optional": true
|
|
55
|
+
},
|
|
56
|
+
"@bison-lab/tokens": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"@bison-lab/ui": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"@payloadcms/live-preview-react": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"@payloadcms/ui": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
68
|
+
"react": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
33
71
|
},
|
|
34
72
|
"devDependencies": {
|
|
73
|
+
"@payloadcms/live-preview-react": "^3.88.0",
|
|
35
74
|
"@payloadcms/plugin-seo": "^3.88.0",
|
|
75
|
+
"@payloadcms/ui": "^3.88.0",
|
|
76
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
77
|
+
"@testing-library/react": "^16.3.2",
|
|
78
|
+
"@types/react": "^19.2.14",
|
|
79
|
+
"jsdom": "^29.0.1",
|
|
36
80
|
"payload": "^3.88.0",
|
|
81
|
+
"react": "^19.2.4",
|
|
82
|
+
"react-dom": "^19.2.4",
|
|
37
83
|
"tsdown": "^0.21.0",
|
|
38
84
|
"typescript": "^5.9.3",
|
|
39
|
-
"vitest": "^4.1.2"
|
|
85
|
+
"vitest": "^4.1.2",
|
|
86
|
+
"@bison-lab/tokens": "3.7.0",
|
|
87
|
+
"@bison-lab/ui": "3.7.0",
|
|
88
|
+
"@bison-lab/fonts": "3.6.0"
|
|
40
89
|
},
|
|
41
90
|
"publishConfig": {
|
|
42
91
|
"access": "public"
|