@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/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-Wut0nzJQ.d.mts.map
55
+ //# sourceMappingURL=title-B2-gWQZd.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"title-Wut0nzJQ.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"}
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": "0.1.0",
4
- "description": "Site-agnostic Payload CMS configuration for Bison Lab sites: the SEO tab on a collection and the metadata reader for the pages it describes",
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
- "payload": "^3.0.0"
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"