@bison-lab/payload-core 3.9.0 → 3.11.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 +16 -9
- package/dist/admin.d.mts +34 -13
- package/dist/admin.d.mts.map +1 -1
- package/dist/admin.mjs +726 -371
- package/dist/admin.mjs.map +1 -1
- package/dist/identity-DZOb3_Gk.mjs +383 -0
- package/dist/identity-DZOb3_Gk.mjs.map +1 -0
- package/dist/index.d.mts +30 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +285 -196
- package/dist/index.mjs.map +1 -1
- package/dist/{map-BUDkX8g1.mjs → looks-BbL309kO.mjs} +94 -6
- package/dist/looks-BbL309kO.mjs.map +1 -0
- package/dist/{library-BGq4wGif.d.mts → looks-DsizRfFV.d.mts} +62 -8
- package/dist/looks-DsizRfFV.d.mts.map +1 -0
- package/dist/react.mjs +28 -3
- package/dist/react.mjs.map +1 -1
- package/dist/theme.d.mts +11 -2
- package/dist/theme.d.mts.map +1 -1
- package/dist/theme.mjs +40 -4
- package/dist/theme.mjs.map +1 -1
- package/package.json +4 -3
- package/dist/identity-D1X0Om4Z.mjs +0 -198
- package/dist/identity-D1X0Om4Z.mjs.map +0 -1
- package/dist/library-BGq4wGif.d.mts.map +0 -1
- package/dist/map-BUDkX8g1.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as documentTitle, r as titleTemplate, t as SHARE_IMAGE_SIZE } from "./share-image-C4ILz4p2.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { A as THEME_IDENTITY_FALLBACK, C as THEME_APPEARANCE_FIELD, D as THEME_DOCUMENT_CONTROLS, E as THEME_CONTRAST_REPORT, F as THEME_SECTION_HEADING, I as headingSelectValue, M as THEME_PAIRING_FIELD, N as THEME_PUBLISH_FIELD, O as THEME_FONT_FIELD, P as THEME_SAVE_BUTTON, S as LOOK_FIELD, T as THEME_COLOR_SCALE_FIELD, _ as docFromConfig, a as pageEditorLooks, b as validateSourceIncluded, c as deleteLibraryColor, d as SYSTEM_COLOR_KEYS, f as THEME_APPEARANCE_SLUG, g as THEME_TYPOGRAPHY_SLUG, h as THEME_SLUG, i as PAGE_EDITOR_SYSTEM_KEYS, j as THEME_LIBRARY_FIELD, k as THEME_GREY_SCALE_FIELD, l as rewriteColorToken, m as THEME_IDENTITY_SLUG, n as colorTokenField, o as pageEditorTokens, p as THEME_COLORS_SLUG, r as lookField, s as themeLibraryFromDoc, t as resolveThemeIdentity, u as themeColorKeys, w as THEME_COLOR_FIELD, x as validateThemeHex, y as themeConfigFromDoc } from "./identity-DZOb3_Gk.mjs";
|
|
3
3
|
import { seoPlugin as seoPlugin$1 } from "@payloadcms/plugin-seo";
|
|
4
4
|
import { catalog } from "@bison-lab/fonts";
|
|
5
|
-
import { SHADE_STEPS, presetHints } from "@bison-lab/tokens";
|
|
5
|
+
import { DESTRUCTIVE_SCALE_HEX, SHADE_STEPS, presetHints } from "@bison-lab/tokens";
|
|
6
6
|
//#region src/seo/fields.ts
|
|
7
7
|
/**
|
|
8
8
|
* The index switch, last in the SEO tab. Off by default: a page is public
|
|
@@ -163,12 +163,6 @@ const APPEARANCE_CHOICES = {
|
|
|
163
163
|
};
|
|
164
164
|
//#endregion
|
|
165
165
|
//#region src/theme/publish.ts
|
|
166
|
-
const THEME_CHILDREN = [
|
|
167
|
-
"colors",
|
|
168
|
-
"typography",
|
|
169
|
-
"appearance",
|
|
170
|
-
"identity"
|
|
171
|
-
];
|
|
172
166
|
/**
|
|
173
167
|
* Publishing a child writes that slice only. Other responsibilities stay
|
|
174
168
|
* as they already are on the stored document. Unsaved form state on a
|
|
@@ -196,11 +190,52 @@ function publishThemeChild(stored, incoming, child) {
|
|
|
196
190
|
logoMark: incoming.logoMark
|
|
197
191
|
};
|
|
198
192
|
}
|
|
199
|
-
function
|
|
200
|
-
|
|
193
|
+
function sliceFromTheme(theme, child) {
|
|
194
|
+
if (child === "colors") return { colors: theme.colors };
|
|
195
|
+
if (child === "typography") return { typography: theme.typography };
|
|
196
|
+
if (child === "appearance") return { appearance: theme.appearance };
|
|
197
|
+
return {
|
|
198
|
+
logo: theme.logo,
|
|
199
|
+
favicon: theme.favicon,
|
|
200
|
+
logoMark: theme.logoMark
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function colorHex(color) {
|
|
204
|
+
if (typeof color === "string") return color;
|
|
205
|
+
return color?.hex ?? void 0;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* A Theme page is a real Global. Hydrate from the store only when this
|
|
209
|
+
* page has never been saved — otherwise afterRead would overwrite the form.
|
|
210
|
+
*/
|
|
211
|
+
function hasThemeSlice(doc, child) {
|
|
212
|
+
if (!doc) return false;
|
|
213
|
+
if (child === "colors") return Boolean(colorHex(doc.colors?.brand?.primary));
|
|
214
|
+
if (child === "typography") return Boolean(doc.typography?.body);
|
|
215
|
+
if (child === "appearance") return Boolean(doc.appearance?.radius);
|
|
216
|
+
return Boolean(doc.logo || doc.favicon || doc.logoMark);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Save on a Theme page writes that slice onto the hidden `theme` row.
|
|
220
|
+
* Other children stay as stored.
|
|
221
|
+
*/
|
|
222
|
+
async function persistThemeChild(payload, incoming, child) {
|
|
223
|
+
const next = publishThemeChild(await payload.findGlobal({
|
|
224
|
+
slug: "theme",
|
|
225
|
+
draft: false,
|
|
226
|
+
overrideAccess: true
|
|
227
|
+
}) ?? {}, incoming, child);
|
|
228
|
+
await payload.updateGlobal({
|
|
229
|
+
slug: THEME_SLUG,
|
|
230
|
+
data: next,
|
|
231
|
+
draft: false
|
|
232
|
+
});
|
|
233
|
+
return next;
|
|
201
234
|
}
|
|
202
235
|
//#endregion
|
|
203
236
|
//#region src/theme/global.ts
|
|
237
|
+
/** Same value as tokens `SUCCESS_SCALE_HEX`. Inlined so an older tokens peer still boots. */
|
|
238
|
+
const LIBRARY_SUCCESS_HEX = "#22c55e";
|
|
204
239
|
function requireAccess$1(options) {
|
|
205
240
|
const read = options.access?.read;
|
|
206
241
|
const update = options.access?.update;
|
|
@@ -211,9 +246,7 @@ function requireAccess$1(options) {
|
|
|
211
246
|
};
|
|
212
247
|
}
|
|
213
248
|
function requireDestructive(options) {
|
|
214
|
-
|
|
215
|
-
if (!hex) throw new Error("createTheme requires a destructive hex: pass options.destructive or seed.brandDestructive. There is no package default.");
|
|
216
|
-
return hex;
|
|
249
|
+
return options.destructive ?? options.seed.brandDestructive ?? DESTRUCTIVE_SCALE_HEX;
|
|
217
250
|
}
|
|
218
251
|
function namedSelect(name, label, choices, defaultValue, field) {
|
|
219
252
|
return {
|
|
@@ -306,7 +339,10 @@ function systemColorGroup(name, label, hexDefault) {
|
|
|
306
339
|
type: "group",
|
|
307
340
|
label,
|
|
308
341
|
fields: colorScaleFields(hexDefault),
|
|
309
|
-
admin: {
|
|
342
|
+
admin: {
|
|
343
|
+
components: { Field: THEME_COLOR_SCALE_FIELD },
|
|
344
|
+
hideGutter: true
|
|
345
|
+
}
|
|
310
346
|
};
|
|
311
347
|
}
|
|
312
348
|
function fontField(name, label, defaultValue, fonts, fontsBaseUrl, sameAsBody) {
|
|
@@ -334,212 +370,265 @@ function fontField(name, label, defaultValue, fonts, fontsBaseUrl, sameAsBody) {
|
|
|
334
370
|
}
|
|
335
371
|
};
|
|
336
372
|
}
|
|
337
|
-
function
|
|
338
|
-
return {
|
|
339
|
-
name:
|
|
340
|
-
type: "
|
|
373
|
+
function colorsFields(seed, destructive) {
|
|
374
|
+
return [{
|
|
375
|
+
name: "colors",
|
|
376
|
+
type: "group",
|
|
377
|
+
label: false,
|
|
341
378
|
admin: {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Settings → Theme children: Colors, Typography, Appearance, Identity.
|
|
349
|
-
* Each child publishes itself. No draft mode: a save is live.
|
|
350
|
-
* `getPublishedTheme` reads that row. There is no Theme preview pane.
|
|
351
|
-
*/
|
|
352
|
-
function createTheme(options) {
|
|
353
|
-
const access = requireAccess$1(options);
|
|
354
|
-
const destructive = requireDestructive(options);
|
|
355
|
-
const { seed, fonts = catalog, fontsBaseUrl = "/fonts", contrastTarget = 7, logo, identity, onPublish } = options;
|
|
356
|
-
const tabs = [
|
|
357
|
-
{
|
|
358
|
-
label: "Colors",
|
|
359
|
-
fields: [
|
|
360
|
-
publishField("colors"),
|
|
361
|
-
{
|
|
362
|
-
name: "colors",
|
|
363
|
-
type: "group",
|
|
364
|
-
label: "Colors",
|
|
365
|
-
fields: [
|
|
366
|
-
{
|
|
367
|
-
name: "brand",
|
|
368
|
-
type: "group",
|
|
369
|
-
label: "Colors",
|
|
370
|
-
fields: [
|
|
371
|
-
{
|
|
372
|
-
name: "themeColorsHeading",
|
|
373
|
-
type: "ui",
|
|
374
|
-
admin: {
|
|
375
|
-
components: { Field: THEME_SECTION_HEADING },
|
|
376
|
-
custom: {
|
|
377
|
-
title: "Theme colors",
|
|
378
|
-
hint: "House semantic fills page editors can pick. Custom colors sit with these."
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
},
|
|
382
|
-
systemColorGroup("primary", "Primary", seed.brandPrimary),
|
|
383
|
-
systemColorGroup("secondary", "Secondary", seed.brandSecondary),
|
|
384
|
-
systemColorGroup("accent", "Accent", seed.brandAccent),
|
|
385
|
-
systemColorGroup("highlight", "Highlight", seed.brandHighlight),
|
|
386
|
-
{
|
|
387
|
-
name: "statusColorsHeading",
|
|
388
|
-
type: "ui",
|
|
389
|
-
admin: {
|
|
390
|
-
components: { Field: THEME_SECTION_HEADING },
|
|
391
|
-
custom: {
|
|
392
|
-
title: "Success and Destructive",
|
|
393
|
-
hint: "Theme chrome only. These are not offered as fills when someone is writing a page."
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
},
|
|
397
|
-
systemColorGroup("success", "Success", seed.brandSuccess),
|
|
398
|
-
systemColorGroup("destructive", "Destructive", destructive)
|
|
399
|
-
]
|
|
400
|
-
},
|
|
401
|
-
namedSelect("greyScale", "Gray family", presetHints.greyScale, seed.greyScale, THEME_GREY_SCALE_FIELD),
|
|
402
|
-
{
|
|
403
|
-
name: "library",
|
|
404
|
-
type: "array",
|
|
405
|
-
label: "Custom colors",
|
|
406
|
-
labels: {
|
|
407
|
-
singular: "Color",
|
|
408
|
-
plural: "Colors"
|
|
409
|
-
},
|
|
410
|
-
fields: [
|
|
411
|
-
{
|
|
412
|
-
name: "key",
|
|
413
|
-
type: "text",
|
|
414
|
-
label: "Key",
|
|
415
|
-
required: true,
|
|
416
|
-
admin: { hidden: true }
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
name: "label",
|
|
420
|
-
type: "text",
|
|
421
|
-
label: "Name",
|
|
422
|
-
required: true,
|
|
423
|
-
admin: { hidden: true }
|
|
424
|
-
},
|
|
425
|
-
...colorScaleFields()
|
|
426
|
-
],
|
|
427
|
-
admin: { components: { Field: THEME_LIBRARY_FIELD } }
|
|
428
|
-
}
|
|
429
|
-
]
|
|
430
|
-
},
|
|
431
|
-
{
|
|
432
|
-
name: "contrast",
|
|
433
|
-
type: "ui",
|
|
434
|
-
admin: {
|
|
435
|
-
components: { Field: THEME_CONTRAST_REPORT },
|
|
436
|
-
custom: { target: contrastTarget }
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
]
|
|
379
|
+
hideGutter: true,
|
|
380
|
+
width: "100%"
|
|
440
381
|
},
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
name: "typography",
|
|
382
|
+
fields: [
|
|
383
|
+
{
|
|
384
|
+
name: "brand",
|
|
445
385
|
type: "group",
|
|
446
|
-
label:
|
|
386
|
+
label: false,
|
|
387
|
+
admin: {
|
|
388
|
+
hideGutter: true,
|
|
389
|
+
width: "100%"
|
|
390
|
+
},
|
|
447
391
|
fields: [
|
|
448
|
-
fontField("heading", "Heading font", headingSelectValue(seed.fontHeading), fonts, fontsBaseUrl, true),
|
|
449
|
-
fontField("body", "Body font", seed.fontBody, fonts, fontsBaseUrl, false),
|
|
450
392
|
{
|
|
451
|
-
name: "
|
|
393
|
+
name: "themeColorsHeading",
|
|
394
|
+
type: "ui",
|
|
395
|
+
admin: {
|
|
396
|
+
components: { Field: THEME_SECTION_HEADING },
|
|
397
|
+
custom: {
|
|
398
|
+
title: "Brand colors",
|
|
399
|
+
hint: "These colors define the visual identity of the site. Adjust them freely to match the brand."
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
systemColorGroup("primary", "Primary", seed.brandPrimary),
|
|
404
|
+
systemColorGroup("secondary", "Secondary", seed.brandSecondary),
|
|
405
|
+
systemColorGroup("accent", "Accent", seed.brandAccent),
|
|
406
|
+
systemColorGroup("highlight", "Highlight", seed.brandHighlight),
|
|
407
|
+
{
|
|
408
|
+
name: "libraryPlacement",
|
|
409
|
+
type: "ui",
|
|
410
|
+
admin: {
|
|
411
|
+
components: { Field: THEME_LIBRARY_FIELD },
|
|
412
|
+
custom: { dataPath: "colors.library" }
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
name: "greyPlacement",
|
|
452
417
|
type: "ui",
|
|
453
418
|
admin: {
|
|
454
|
-
components: { Field:
|
|
455
|
-
custom: {
|
|
419
|
+
components: { Field: THEME_GREY_SCALE_FIELD },
|
|
420
|
+
custom: { dataPath: "colors.greyScale" }
|
|
456
421
|
}
|
|
457
|
-
}
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: "statusColorsHeading",
|
|
425
|
+
type: "ui",
|
|
426
|
+
admin: {
|
|
427
|
+
components: { Field: THEME_SECTION_HEADING },
|
|
428
|
+
custom: {
|
|
429
|
+
title: "Status colors",
|
|
430
|
+
hint: "These colors communicate meaning across the site. You can adjust them to fit your brand, but we'll help keep them recognizable as success and error states."
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
systemColorGroup("success", "Success", seed.brandSuccess || LIBRARY_SUCCESS_HEX),
|
|
435
|
+
systemColorGroup("destructive", "Destructive", destructive)
|
|
458
436
|
]
|
|
459
|
-
}, publishField("typography")]
|
|
460
|
-
},
|
|
461
|
-
{
|
|
462
|
-
label: "Appearance",
|
|
463
|
-
fields: [{
|
|
464
|
-
name: "appearance",
|
|
465
|
-
type: "group",
|
|
466
|
-
label: "Appearance",
|
|
467
|
-
fields: [
|
|
468
|
-
namedSelect("defaultTheme", "Default theme", APPEARANCE_CHOICES.defaultTheme, seed.defaultTheme),
|
|
469
|
-
namedSelect("radius", "Corner style", APPEARANCE_CHOICES.radius, seed.radius),
|
|
470
|
-
namedSelect("shadow", "Depth", APPEARANCE_CHOICES.shadow, seed.shadow),
|
|
471
|
-
namedSelect("motion", "Motion", APPEARANCE_CHOICES.motion, seed.motion),
|
|
472
|
-
namedSelect("density", "Spacing", APPEARANCE_CHOICES.density, seed.density)
|
|
473
|
-
],
|
|
474
|
-
admin: { components: { Field: THEME_APPEARANCE_FIELD } }
|
|
475
|
-
}, publishField("appearance")]
|
|
476
|
-
}
|
|
477
|
-
];
|
|
478
|
-
if (logo) tabs.push({
|
|
479
|
-
label: "Identity",
|
|
480
|
-
fields: [
|
|
481
|
-
{
|
|
482
|
-
name: "logo",
|
|
483
|
-
type: "upload",
|
|
484
|
-
relationTo: logo.collection,
|
|
485
|
-
label: "Logo",
|
|
486
|
-
admin: { description: "The full wordmark used in the header and footer." }
|
|
487
437
|
},
|
|
488
438
|
{
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
439
|
+
...namedSelect("greyScale", "Gray family", presetHints.greyScale, seed.greyScale, THEME_GREY_SCALE_FIELD),
|
|
440
|
+
admin: {
|
|
441
|
+
hidden: true,
|
|
442
|
+
components: { Field: THEME_GREY_SCALE_FIELD }
|
|
443
|
+
}
|
|
494
444
|
},
|
|
495
445
|
{
|
|
496
|
-
name: "
|
|
497
|
-
type: "
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
446
|
+
name: "library",
|
|
447
|
+
type: "array",
|
|
448
|
+
label: "Additional colors",
|
|
449
|
+
labels: {
|
|
450
|
+
singular: "Color",
|
|
451
|
+
plural: "Colors"
|
|
452
|
+
},
|
|
453
|
+
fields: [
|
|
454
|
+
{
|
|
455
|
+
name: "key",
|
|
456
|
+
type: "text",
|
|
457
|
+
label: "Key",
|
|
458
|
+
required: true,
|
|
459
|
+
admin: { hidden: true }
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
name: "label",
|
|
463
|
+
type: "text",
|
|
464
|
+
label: "Name",
|
|
465
|
+
required: true,
|
|
466
|
+
admin: { hidden: true }
|
|
467
|
+
},
|
|
468
|
+
...colorScaleFields()
|
|
469
|
+
],
|
|
470
|
+
admin: {
|
|
471
|
+
hidden: true,
|
|
472
|
+
components: { Field: THEME_LIBRARY_FIELD },
|
|
473
|
+
width: "100%"
|
|
474
|
+
}
|
|
475
|
+
}
|
|
503
476
|
]
|
|
504
|
-
});
|
|
505
|
-
const fields = [{
|
|
506
|
-
type: "tabs",
|
|
507
|
-
tabs
|
|
508
|
-
}, {
|
|
509
|
-
name: "publishChild",
|
|
510
|
-
type: "text",
|
|
511
|
-
admin: { hidden: true }
|
|
512
477
|
}];
|
|
478
|
+
}
|
|
479
|
+
function typographyFields(seed, fonts, fontsBaseUrl) {
|
|
480
|
+
return [{
|
|
481
|
+
name: "typography",
|
|
482
|
+
type: "group",
|
|
483
|
+
label: "Typography",
|
|
484
|
+
fields: [
|
|
485
|
+
fontField("heading", "Heading font", headingSelectValue(seed.fontHeading), fonts, fontsBaseUrl, true),
|
|
486
|
+
fontField("body", "Body font", seed.fontBody, fonts, fontsBaseUrl, false),
|
|
487
|
+
{
|
|
488
|
+
name: "pairing",
|
|
489
|
+
type: "ui",
|
|
490
|
+
admin: {
|
|
491
|
+
components: { Field: THEME_PAIRING_FIELD },
|
|
492
|
+
custom: { fontsBaseUrl }
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
]
|
|
496
|
+
}];
|
|
497
|
+
}
|
|
498
|
+
function appearanceFields(seed) {
|
|
499
|
+
return [{
|
|
500
|
+
name: "appearance",
|
|
501
|
+
type: "group",
|
|
502
|
+
label: "Appearance",
|
|
503
|
+
fields: [
|
|
504
|
+
namedSelect("defaultTheme", "Default theme", APPEARANCE_CHOICES.defaultTheme, seed.defaultTheme),
|
|
505
|
+
namedSelect("radius", "Corner style", APPEARANCE_CHOICES.radius, seed.radius),
|
|
506
|
+
namedSelect("shadow", "Depth", APPEARANCE_CHOICES.shadow, seed.shadow),
|
|
507
|
+
namedSelect("motion", "Motion", APPEARANCE_CHOICES.motion, seed.motion),
|
|
508
|
+
namedSelect("density", "Spacing", APPEARANCE_CHOICES.density, seed.density)
|
|
509
|
+
],
|
|
510
|
+
admin: { components: { Field: THEME_APPEARANCE_FIELD } }
|
|
511
|
+
}];
|
|
512
|
+
}
|
|
513
|
+
function identityFields(collection) {
|
|
514
|
+
return [
|
|
515
|
+
{
|
|
516
|
+
name: "logo",
|
|
517
|
+
type: "upload",
|
|
518
|
+
relationTo: collection,
|
|
519
|
+
label: "Logo",
|
|
520
|
+
admin: { description: "The full wordmark used in the header and footer." }
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: "favicon",
|
|
524
|
+
type: "upload",
|
|
525
|
+
relationTo: collection,
|
|
526
|
+
label: "Favicon",
|
|
527
|
+
admin: { description: "The small icon in the browser tab. PNG or SVG." }
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
name: "logoMark",
|
|
531
|
+
type: "upload",
|
|
532
|
+
relationTo: collection,
|
|
533
|
+
label: "Mobile menu logo",
|
|
534
|
+
admin: { description: "Optional. Used when the full logo is too wide for the mobile menu — typically the mark." }
|
|
535
|
+
}
|
|
536
|
+
];
|
|
537
|
+
}
|
|
538
|
+
function pageHooks(child) {
|
|
513
539
|
return {
|
|
540
|
+
beforeChange: [async ({ data, req }) => {
|
|
541
|
+
if (req?.payload) await persistThemeChild(req.payload, data, child);
|
|
542
|
+
return data;
|
|
543
|
+
}],
|
|
544
|
+
afterRead: [async ({ doc, req }) => {
|
|
545
|
+
if (hasThemeSlice(doc, child)) return doc;
|
|
546
|
+
const theme = await req?.payload?.findGlobal({
|
|
547
|
+
slug: THEME_SLUG,
|
|
548
|
+
draft: false,
|
|
549
|
+
depth: child === "identity" ? 1 : 0,
|
|
550
|
+
overrideAccess: true
|
|
551
|
+
});
|
|
552
|
+
if (!theme) return doc;
|
|
553
|
+
return {
|
|
554
|
+
...doc,
|
|
555
|
+
...sliceFromTheme(theme, child)
|
|
556
|
+
};
|
|
557
|
+
}]
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Standard Payload Globals in an `admin.group: "Theme"` nav section —
|
|
562
|
+
* the same pattern as Content and Settings. Each page is its own Global
|
|
563
|
+
* (Save, fields, access). A hidden `theme` store is the published read
|
|
564
|
+
* model `getPublishedTheme` already knows. Locking is off: these are
|
|
565
|
+
* settings forms, not collaborative documents. No draft mode, no preview
|
|
566
|
+
* pane.
|
|
567
|
+
*/
|
|
568
|
+
function createTheme(options) {
|
|
569
|
+
const access = requireAccess$1(options);
|
|
570
|
+
const destructive = requireDestructive(options);
|
|
571
|
+
const { seed, fonts = catalog, fontsBaseUrl = "/fonts", contrastTarget = 7, logo, identity, onPublish } = options;
|
|
572
|
+
const adminCustom = {
|
|
573
|
+
contrastTarget,
|
|
574
|
+
fontsBaseUrl,
|
|
575
|
+
identityFallback: identity?.fallback
|
|
576
|
+
};
|
|
577
|
+
const colorFields = colorsFields(seed, destructive);
|
|
578
|
+
const typeFields = typographyFields(seed, fonts, fontsBaseUrl);
|
|
579
|
+
const lookFields = appearanceFields(seed);
|
|
580
|
+
const markFields = logo ? identityFields(logo.collection) : [];
|
|
581
|
+
const store = {
|
|
514
582
|
slug: THEME_SLUG,
|
|
515
583
|
label: "Theme",
|
|
584
|
+
lockDocuments: false,
|
|
516
585
|
admin: {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
fontsBaseUrl,
|
|
521
|
-
identityFallback: identity?.fallback
|
|
522
|
-
},
|
|
523
|
-
components: { elements: { SaveButton: THEME_SAVE_BUTTON } }
|
|
586
|
+
hidden: true,
|
|
587
|
+
hideAPIURL: true,
|
|
588
|
+
custom: adminCustom
|
|
524
589
|
},
|
|
525
590
|
access: {
|
|
526
591
|
read: access.read,
|
|
527
592
|
update: access.update
|
|
528
593
|
},
|
|
529
|
-
fields
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
}]
|
|
541
|
-
}
|
|
594
|
+
fields: [
|
|
595
|
+
...colorFields,
|
|
596
|
+
...typeFields,
|
|
597
|
+
...lookFields,
|
|
598
|
+
...markFields
|
|
599
|
+
],
|
|
600
|
+
hooks: { afterChange: [async ({ doc }) => {
|
|
601
|
+
if (!onPublish) return;
|
|
602
|
+
const themeDoc = doc;
|
|
603
|
+
await onPublish(themeConfigFromDoc(themeDoc, seed), themeDoc);
|
|
604
|
+
}] }
|
|
542
605
|
};
|
|
606
|
+
function page(slug, label, child, fields, preview) {
|
|
607
|
+
return {
|
|
608
|
+
slug,
|
|
609
|
+
label,
|
|
610
|
+
lockDocuments: false,
|
|
611
|
+
admin: {
|
|
612
|
+
group: "Theme",
|
|
613
|
+
hideAPIURL: true,
|
|
614
|
+
custom: adminCustom,
|
|
615
|
+
components: preview ? { elements: { beforeDocumentControls: [THEME_DOCUMENT_CONTROLS] } } : void 0
|
|
616
|
+
},
|
|
617
|
+
access: {
|
|
618
|
+
read: access.read,
|
|
619
|
+
update: access.update
|
|
620
|
+
},
|
|
621
|
+
fields,
|
|
622
|
+
hooks: pageHooks(child)
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
return [
|
|
626
|
+
store,
|
|
627
|
+
page(THEME_COLORS_SLUG, "Colors", "colors", colorFields, true),
|
|
628
|
+
page(THEME_TYPOGRAPHY_SLUG, "Typography", "typography", typeFields, true),
|
|
629
|
+
page(THEME_APPEARANCE_SLUG, "Appearance", "appearance", lookFields, true),
|
|
630
|
+
...logo ? [page(THEME_IDENTITY_SLUG, "Identity", "identity", markFields, false)] : []
|
|
631
|
+
];
|
|
543
632
|
}
|
|
544
633
|
//#endregion
|
|
545
634
|
//#region src/brand-assets/sanitize.ts
|
|
@@ -688,6 +777,6 @@ const THEME_PREVIEW_BREAKPOINTS = [
|
|
|
688
777
|
}
|
|
689
778
|
];
|
|
690
779
|
//#endregion
|
|
691
|
-
export { BRAND_ASSETS_MIME_TYPES, BRAND_ASSETS_SLUG, DESCRIPTION_LENGTH, SHARE_IMAGE_SIZE, SYSTEM_COLOR_KEYS, THEME_APPEARANCE_FIELD, THEME_COLOR_FIELD, THEME_COLOR_SCALE_FIELD, THEME_CONTRAST_REPORT, THEME_FONT_FIELD, THEME_GREY_SCALE_FIELD, THEME_LIBRARY_FIELD, THEME_PAIRING_FIELD, THEME_PREVIEW_BREAKPOINTS, THEME_PUBLISH_FIELD, THEME_SAVE_BUTTON, THEME_SECTION_HEADING, THEME_SLUG, createBrandAssets, createTheme, deleteLibraryColor, documentTitle, firstImageIn, noIndexField, publishThemeChild, resolveThemeIdentity, rewriteColorToken, sanitizeSvg, seedTheme, seoPlugin, themeColorKeys, titleTemplate, truncateAtWord };
|
|
780
|
+
export { BRAND_ASSETS_MIME_TYPES, BRAND_ASSETS_SLUG, DESCRIPTION_LENGTH, LOOK_FIELD, PAGE_EDITOR_SYSTEM_KEYS, SHARE_IMAGE_SIZE, SYSTEM_COLOR_KEYS, THEME_APPEARANCE_FIELD, THEME_APPEARANCE_SLUG, THEME_COLORS_SLUG, THEME_COLOR_FIELD, THEME_COLOR_SCALE_FIELD, THEME_CONTRAST_REPORT, THEME_DOCUMENT_CONTROLS, THEME_FONT_FIELD, THEME_GREY_SCALE_FIELD, THEME_IDENTITY_FALLBACK, THEME_IDENTITY_SLUG, THEME_LIBRARY_FIELD, THEME_PAIRING_FIELD, THEME_PREVIEW_BREAKPOINTS, THEME_PUBLISH_FIELD, THEME_SAVE_BUTTON, THEME_SECTION_HEADING, THEME_SLUG, THEME_TYPOGRAPHY_SLUG, colorTokenField, createBrandAssets, createTheme, deleteLibraryColor, documentTitle, firstImageIn, lookField, noIndexField, pageEditorLooks, pageEditorTokens, persistThemeChild, publishThemeChild, resolveThemeIdentity, rewriteColorToken, sanitizeSvg, seedTheme, seoPlugin, themeColorKeys, themeLibraryFromDoc, titleTemplate, truncateAtWord };
|
|
692
781
|
|
|
693
782
|
//# sourceMappingURL=index.mjs.map
|