@bison-lab/payload-core 3.9.0 → 3.10.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 +5 -5
- package/dist/admin.d.mts +20 -11
- package/dist/admin.d.mts.map +1 -1
- package/dist/admin.mjs +213 -137
- package/dist/admin.mjs.map +1 -1
- package/dist/{identity-D1X0Om4Z.mjs → identity-Bg-G05mb.mjs} +5 -4
- package/dist/identity-Bg-G05mb.mjs.map +1 -0
- package/dist/index.d.mts +6 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +92 -99
- package/dist/index.mjs.map +1 -1
- package/dist/theme.mjs +1 -1
- package/package.json +4 -3
- package/dist/identity-D1X0Om4Z.mjs.map +0 -1
package/dist/admin.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { FieldDescription, FieldError, FieldLabel, useField, useForm, useFormFie
|
|
|
4
4
|
import { GREY_SCALES, SHADE_STEPS, contrastForeground, contrastRatio, createColorScale, hexToHSL, hslToString, includedShadeSteps, isThemeHex, presetHints, regenerateColorScale, setColorScaleInclude, updateColorScale } from "@bison-lab/tokens";
|
|
5
5
|
import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { createPortal } from "react-dom";
|
|
7
8
|
import { findFont, fontFaceCss, isFontId } from "@bison-lab/fonts";
|
|
8
9
|
//#region src/admin/color-field.tsx
|
|
9
10
|
const HEX_ERROR = "Enter a six-digit hex colour like #1e3a5f";
|
|
@@ -40,7 +41,7 @@ const ColorField = ({ field, path, readOnly }) => {
|
|
|
40
41
|
/* @__PURE__ */ jsx("style", {
|
|
41
42
|
href: "bl-color-field",
|
|
42
43
|
precedence: "default",
|
|
43
|
-
children: CSS$
|
|
44
|
+
children: CSS$4
|
|
44
45
|
}),
|
|
45
46
|
/* @__PURE__ */ jsx(FieldLabel, {
|
|
46
47
|
htmlFor: hexId,
|
|
@@ -99,7 +100,7 @@ const ColorField = ({ field, path, readOnly }) => {
|
|
|
99
100
|
]
|
|
100
101
|
});
|
|
101
102
|
};
|
|
102
|
-
const CSS$
|
|
103
|
+
const CSS$4 = `
|
|
103
104
|
.bl-color-field__control{display:flex;align-items:center;gap:calc(var(--base) * .4)}
|
|
104
105
|
.bl-color-field__swatch{flex:none;width:calc(var(--base) * 1.6);height:calc(var(--base) * 1.6);border:1px solid var(--theme-elevation-150);border-radius:var(--style-radius-s);background:var(--theme-elevation-50)}
|
|
105
106
|
.bl-color-field__picker{flex:none;width:calc(var(--base) * 2);height:calc(var(--base) * 2);padding:0;border:1px solid var(--theme-elevation-150);border-radius:var(--style-radius-s);background:transparent;cursor:pointer}
|
|
@@ -351,9 +352,16 @@ const READABILITY_PUBLISH_NOTE = "You can still publish. To improve a color, dar
|
|
|
351
352
|
//#region src/admin/preview-mode.tsx
|
|
352
353
|
const ATTR = "data-bl-theme-preview";
|
|
353
354
|
const EVENT = "bl-theme-preview";
|
|
355
|
+
function adminIsDark() {
|
|
356
|
+
if (typeof document === "undefined") return false;
|
|
357
|
+
const root = document.documentElement;
|
|
358
|
+
return root.getAttribute("data-theme") === "dark" || root.getAttribute("data-theme-pref") === "dark" || root.classList.contains("dark");
|
|
359
|
+
}
|
|
354
360
|
function readMode() {
|
|
355
361
|
if (typeof document === "undefined") return "light";
|
|
356
|
-
|
|
362
|
+
const set = document.documentElement.getAttribute(ATTR);
|
|
363
|
+
if (set === "dark" || set === "light") return set;
|
|
364
|
+
return adminIsDark() ? "dark" : "light";
|
|
357
365
|
}
|
|
358
366
|
function setThemePreviewMode(mode) {
|
|
359
367
|
if (typeof document === "undefined") return;
|
|
@@ -361,9 +369,10 @@ function setThemePreviewMode(mode) {
|
|
|
361
369
|
window.dispatchEvent(new Event(EVENT));
|
|
362
370
|
}
|
|
363
371
|
function useThemePreviewMode() {
|
|
364
|
-
const [mode, setMode] = useState(
|
|
372
|
+
const [mode, setMode] = useState("light");
|
|
365
373
|
useEffect(() => {
|
|
366
374
|
const sync = () => setMode(readMode());
|
|
375
|
+
sync();
|
|
367
376
|
window.addEventListener(EVENT, sync);
|
|
368
377
|
return () => window.removeEventListener(EVENT, sync);
|
|
369
378
|
}, []);
|
|
@@ -374,24 +383,36 @@ function ThemePreviewToggle() {
|
|
|
374
383
|
return /* @__PURE__ */ jsxs("div", {
|
|
375
384
|
className: "bl-preview-toggle",
|
|
376
385
|
role: "group",
|
|
377
|
-
"aria-label": "Preview
|
|
378
|
-
children: [/* @__PURE__ */ jsx("
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
386
|
+
"aria-label": "Preview fills in",
|
|
387
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
388
|
+
className: "bl-preview-toggle__label",
|
|
389
|
+
children: "Preview fills"
|
|
390
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
391
|
+
className: "bl-preview-toggle__pills",
|
|
392
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
393
|
+
type: "button",
|
|
394
|
+
"aria-pressed": mode === "light",
|
|
395
|
+
onClick: () => setThemePreviewMode("light"),
|
|
396
|
+
children: "Light"
|
|
397
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
398
|
+
type: "button",
|
|
399
|
+
"aria-pressed": mode === "dark",
|
|
400
|
+
onClick: () => setThemePreviewMode("dark"),
|
|
401
|
+
children: "Dark"
|
|
402
|
+
})]
|
|
388
403
|
})]
|
|
389
404
|
});
|
|
390
405
|
}
|
|
391
406
|
const THEME_PREVIEW_TOGGLE_CSS = `
|
|
392
|
-
.bl-preview-toggle{display:inline-flex;
|
|
393
|
-
.bl-preview-
|
|
394
|
-
.bl-preview-
|
|
407
|
+
.bl-preview-toggle{display:inline-flex;align-items:center;gap:.6rem}
|
|
408
|
+
.bl-preview-toggle__label{font-size:12px;font-weight:600;color:#a1a1aa}
|
|
409
|
+
.bl-preview-toggle__pills{display:inline-flex;padding:3px;border:1px solid #3f3f46;border-radius:10px;background:#18181b}
|
|
410
|
+
.bl-preview-toggle__pills button{min-height:2rem;padding:.25rem .8rem;border:0;border-radius:7px;background:transparent;color:#d4d4d8;font:inherit;font-size:13px;font-weight:600;cursor:pointer}
|
|
411
|
+
.bl-preview-toggle__pills button[aria-pressed=true]{background:#f4f4f5;color:#18181b;box-shadow:0 1px 2px rgba(0,0,0,.25)}
|
|
412
|
+
html[data-theme=light] .bl-preview-toggle__label{color:#52525b}
|
|
413
|
+
html[data-theme=light] .bl-preview-toggle__pills{border-color:#d4d4d8;background:#e4e4e7}
|
|
414
|
+
html[data-theme=light] .bl-preview-toggle__pills button{color:#3f3f46}
|
|
415
|
+
html[data-theme=light] .bl-preview-toggle__pills button[aria-pressed=true]{background:#fff;color:#18181b;box-shadow:0 1px 2px rgba(15,23,42,.12)}
|
|
395
416
|
`;
|
|
396
417
|
//#endregion
|
|
397
418
|
//#region src/admin/readability-list.tsx
|
|
@@ -429,25 +450,6 @@ function ReadabilityDetail({ item, target = 7 }) {
|
|
|
429
450
|
]
|
|
430
451
|
});
|
|
431
452
|
}
|
|
432
|
-
function ReadabilityList({ warnings, target = 7 }) {
|
|
433
|
-
const failing = warnings.filter((item) => !item.meets).length;
|
|
434
|
-
return /* @__PURE__ */ jsxs("aside", {
|
|
435
|
-
className: "bl-readability",
|
|
436
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
437
|
-
className: "bl-readability__head",
|
|
438
|
-
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h2", { children: "Readability checks" }), /* @__PURE__ */ jsx("p", { children: "Text the site puts on each fill. Warnings do not block save." })] }), /* @__PURE__ */ jsx("span", {
|
|
439
|
-
"data-attention": failing ? "" : void 0,
|
|
440
|
-
children: failing === 0 ? "All look readable" : `${failing} may be hard to read`
|
|
441
|
-
})]
|
|
442
|
-
}), /* @__PURE__ */ jsx("ul", { children: warnings.map((item) => /* @__PURE__ */ jsxs("li", {
|
|
443
|
-
"data-failing": item.meets ? void 0 : "",
|
|
444
|
-
children: [/* @__PURE__ */ jsx("strong", { children: readabilityHeadline(item) }), /* @__PURE__ */ jsx(ReadabilityDetail, {
|
|
445
|
-
item,
|
|
446
|
-
target
|
|
447
|
-
})]
|
|
448
|
-
}, item.id)) })]
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
453
|
const READABILITY_LIST_CSS = `
|
|
452
454
|
.bl-readability{padding:calc(var(--base,16px) * .8);border:1px solid var(--theme-elevation-150,#e2e8f0);border-radius:var(--style-radius-m,12px);background:var(--theme-elevation-0,#fff)}
|
|
453
455
|
.bl-readability__head{display:flex;justify-content:space-between;gap:1rem;align-items:flex-start}
|
|
@@ -541,13 +543,20 @@ function ColorScaleCard({ id, name, hint, required, custom, state, onChange, onD
|
|
|
541
543
|
}), hint ? /* @__PURE__ */ jsx("p", {
|
|
542
544
|
className: "bl-scale-card__hint",
|
|
543
545
|
children: hint
|
|
544
|
-
}) : null] }),
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
546
|
+
}) : null] }), /* @__PURE__ */ jsxs("div", {
|
|
547
|
+
className: "bl-scale-card__head-actions",
|
|
548
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
549
|
+
className: "bl-scale-card__mark",
|
|
550
|
+
style: { background: state.hex },
|
|
551
|
+
"aria-hidden": "true"
|
|
552
|
+
}), onDelete ? /* @__PURE__ */ jsx("button", {
|
|
553
|
+
type: "button",
|
|
554
|
+
className: "bl-scale-card__delete",
|
|
555
|
+
disabled: readOnly,
|
|
556
|
+
onClick: onDelete,
|
|
557
|
+
children: "Delete"
|
|
558
|
+
}) : null]
|
|
559
|
+
})]
|
|
551
560
|
}),
|
|
552
561
|
/* @__PURE__ */ jsxs("div", {
|
|
553
562
|
className: "bl-scale-card__row",
|
|
@@ -647,7 +656,39 @@ function ColorScaleCard({ id, name, hint, required, custom, state, onChange, onD
|
|
|
647
656
|
onClick: () => toggleStep(step),
|
|
648
657
|
children: [/* @__PURE__ */ jsx("span", {
|
|
649
658
|
className: "bl-scale-card__chip",
|
|
650
|
-
style: { background: hslCss(state.scale[step]) }
|
|
659
|
+
style: { background: hslCss(state.scale[step]) },
|
|
660
|
+
children: source ? null : /* @__PURE__ */ jsx("span", {
|
|
661
|
+
className: "bl-scale-card__intent",
|
|
662
|
+
"data-intent": on ? "exclude" : "include",
|
|
663
|
+
"aria-hidden": "true",
|
|
664
|
+
children: on ? /* @__PURE__ */ jsxs("svg", {
|
|
665
|
+
viewBox: "0 0 24 24",
|
|
666
|
+
width: "16",
|
|
667
|
+
height: "16",
|
|
668
|
+
children: [/* @__PURE__ */ jsx("circle", {
|
|
669
|
+
cx: "12",
|
|
670
|
+
cy: "12",
|
|
671
|
+
r: "8",
|
|
672
|
+
fill: "none",
|
|
673
|
+
stroke: "currentColor",
|
|
674
|
+
strokeWidth: "2.4"
|
|
675
|
+
}), /* @__PURE__ */ jsx("path", {
|
|
676
|
+
d: "M7.2 16.8 16.8 7.2",
|
|
677
|
+
stroke: "currentColor",
|
|
678
|
+
strokeWidth: "2.4"
|
|
679
|
+
})]
|
|
680
|
+
}) : /* @__PURE__ */ jsx("svg", {
|
|
681
|
+
viewBox: "0 0 24 24",
|
|
682
|
+
width: "16",
|
|
683
|
+
height: "16",
|
|
684
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
685
|
+
d: "M12 6v12M6 12h12",
|
|
686
|
+
fill: "none",
|
|
687
|
+
stroke: "currentColor",
|
|
688
|
+
strokeWidth: "2.6"
|
|
689
|
+
})
|
|
690
|
+
})
|
|
691
|
+
})
|
|
651
692
|
}), /* @__PURE__ */ jsx("span", {
|
|
652
693
|
className: "bl-scale-card__step-label",
|
|
653
694
|
children: step
|
|
@@ -655,7 +696,7 @@ function ColorScaleCard({ id, name, hint, required, custom, state, onChange, onD
|
|
|
655
696
|
}, step);
|
|
656
697
|
})
|
|
657
698
|
}),
|
|
658
|
-
open && warning ? /* @__PURE__ */ jsx("div", {
|
|
699
|
+
open && warning ? createPortal(/* @__PURE__ */ jsx("div", {
|
|
659
700
|
className: "bl-scale-card__modal",
|
|
660
701
|
role: "dialog",
|
|
661
702
|
"aria-modal": "true",
|
|
@@ -687,7 +728,7 @@ function ColorScaleCard({ id, name, hint, required, custom, state, onChange, onD
|
|
|
687
728
|
})
|
|
688
729
|
]
|
|
689
730
|
})
|
|
690
|
-
}) : null
|
|
731
|
+
}), document.body) : null
|
|
691
732
|
]
|
|
692
733
|
});
|
|
693
734
|
}
|
|
@@ -702,6 +743,8 @@ const COLOR_SCALE_CARD_CSS = `
|
|
|
702
743
|
.bl-scale-card__status[data-ok]{background:#ecfdf5;color:#047857}
|
|
703
744
|
.bl-scale-card__sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
|
704
745
|
.bl-scale-card__hint{margin:.35rem 0 0;color:var(--theme-elevation-500,#64748b);font-size:12px}
|
|
746
|
+
.bl-scale-card__head-actions{display:flex;align-items:center;gap:.5rem}
|
|
747
|
+
.bl-scale-card__mark{display:block;width:2.5rem;height:2.5rem;border-radius:8px;border:1px solid rgba(15,23,42,.12);flex:none}
|
|
705
748
|
.bl-scale-card__delete{border:0;background:none;color:#be123c;font:inherit;font-size:13px;font-weight:600;cursor:pointer}
|
|
706
749
|
.bl-scale-card__row{display:grid;grid-template-columns:1fr 8rem;gap:.75rem;margin-top:1rem}
|
|
707
750
|
.bl-scale-card__field{display:flex;flex-direction:column;gap:.35rem;font-size:12px;font-weight:600;color:var(--theme-elevation-600,#475569)}
|
|
@@ -715,27 +758,27 @@ const COLOR_SCALE_CARD_CSS = `
|
|
|
715
758
|
.bl-scale-card__warn,.bl-scale-card__stale{margin:.75rem 0 0;padding:.65rem .75rem;border-radius:8px;font-size:12px}
|
|
716
759
|
.bl-scale-card__warn{border:1px solid #a7f3d0;background:#ecfdf5;color:#065f46}
|
|
717
760
|
.bl-scale-card__stale{border:1px solid #fde68a;background:#fffbeb;color:#92400e}
|
|
718
|
-
.bl-scale-card__regen{width:100%;margin-top:.85rem;min-height:2.25rem;border:0;border-radius:8px;background
|
|
719
|
-
.bl-scale-card__regen:disabled{opacity
|
|
761
|
+
.bl-scale-card__regen{width:100%;margin-top:.85rem;min-height:2.25rem;border:0;border-radius:8px;background:#0f172a;color:#fff;font:inherit;font-weight:600;cursor:pointer}
|
|
762
|
+
.bl-scale-card__regen:disabled{background:#1e293b;color:#f8fafc;opacity:1;cursor:not-allowed}
|
|
720
763
|
.bl-scale-card__scale-head{display:flex;justify-content:space-between;margin:1rem 0 .4rem;font-size:12px;color:var(--theme-elevation-500,#64748b)}
|
|
721
764
|
.bl-scale-card__scale-head button{border:0;background:none;padding:0;font:inherit;color:inherit;text-decoration:underline;cursor:pointer}
|
|
722
765
|
.bl-scale-card__steps{display:grid;grid-template-columns:repeat(11,minmax(0,1fr));gap:.45rem 3px}
|
|
723
766
|
.bl-scale-card__step{display:flex;flex-direction:column;align-items:center;gap:.3rem;border:0;padding:0;background:transparent;cursor:pointer}
|
|
724
|
-
.bl-scale-card__chip{display:block;width:100%;height:2.15rem;border-radius:6px}
|
|
767
|
+
.bl-scale-card__chip{position:relative;display:block;width:100%;height:2.15rem;border-radius:6px;overflow:hidden}
|
|
768
|
+
.bl-scale-card__intent{position:absolute;top:3px;right:3px;width:1.15rem;height:1.15rem;border-radius:999px;display:grid;place-items:center;opacity:0;color:#be123c;background:#fff;box-shadow:0 1px 3px rgba(15,23,42,.28);transition:opacity .15s ease,transform .15s ease;pointer-events:none}
|
|
769
|
+
.bl-scale-card__intent[data-intent=include]{color:#047857}
|
|
770
|
+
.bl-scale-card__step:hover:not(:disabled) .bl-scale-card__chip{transform:translateY(-1px)}
|
|
771
|
+
.bl-scale-card__step:hover:not(:disabled) .bl-scale-card__intent{opacity:1}
|
|
725
772
|
.bl-scale-card__step-label{font-size:10px;line-height:1;color:var(--theme-elevation-600,#475569)}
|
|
726
|
-
.bl-scale-card__step[data-source] .bl-scale-card__chip{box-shadow:0 0 0 2px
|
|
727
|
-
.bl-scale-card__step[data-excluded]{opacity:.
|
|
773
|
+
.bl-scale-card__step[data-source] .bl-scale-card__chip{box-shadow:0 0 0 2px var(--theme-elevation-800,#0f172a)}
|
|
774
|
+
.bl-scale-card__step[data-excluded]{opacity:.55}
|
|
728
775
|
.bl-scale-card__step:disabled{cursor:default}
|
|
729
|
-
.bl-scale-card__modal{position:fixed;inset:0;z-index:
|
|
776
|
+
.bl-scale-card__modal{position:fixed;inset:0;z-index:100000;display:grid;place-items:center;padding:1rem;background:rgba(15,23,42,.45)}
|
|
730
777
|
.bl-scale-card__panel{width:min(32rem,100%);padding:1.15rem 1.2rem;border-radius:16px;background:#fff;color:#0f172a}
|
|
731
778
|
.bl-scale-card__panel-head{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem}
|
|
732
779
|
.bl-scale-card__panel-head h4{margin:0;font-size:1rem}
|
|
733
780
|
.bl-scale-card__panel-head button{border:0;background:none;font:inherit;font-size:1.25rem;line-height:1;color:#64748b;cursor:pointer}
|
|
734
781
|
.bl-scale-card__panel-done{margin-top:1rem;min-height:2.1rem;padding:.35rem .85rem;border:0;border-radius:8px;background:#0f172a;color:#fff;font:inherit;font-weight:600;cursor:pointer}
|
|
735
|
-
[data-bl-theme-preview=dark] .bl-scale-card{background:#0f172a;border-color:#334155;color:#f8fafc}
|
|
736
|
-
[data-bl-theme-preview=dark] .bl-scale-card__hint,[data-bl-theme-preview=dark] .bl-scale-card__label-sample p,[data-bl-theme-preview=dark] .bl-scale-card__scale-head,[data-bl-theme-preview=dark] .bl-scale-card__step-label,[data-bl-theme-preview=dark] .bl-scale-card__field{color:#94a3b8}
|
|
737
|
-
[data-bl-theme-preview=dark] .bl-scale-card__hex-wrap,[data-bl-theme-preview=dark] .bl-scale-card__field select{background:#1e293b;border-color:#334155;color:#f8fafc}
|
|
738
|
-
[data-bl-theme-preview=dark] .bl-scale-card__step[data-source] .bl-scale-card__chip{box-shadow:0 0 0 2px #f8fafc}
|
|
739
782
|
` + READABILITY_LIST_CSS;
|
|
740
783
|
//#endregion
|
|
741
784
|
//#region src/admin/color-scale-field.tsx
|
|
@@ -803,7 +846,7 @@ const SYSTEM_COLOR_KEYS = [
|
|
|
803
846
|
"destructive"
|
|
804
847
|
];
|
|
805
848
|
function themeColorKeys(doc) {
|
|
806
|
-
const custom = (doc?.colors?.library
|
|
849
|
+
const custom = (Array.isArray(doc?.colors?.library) ? doc.colors.library : []).map((row) => row.key?.trim()).filter((key) => Boolean(key));
|
|
807
850
|
return [...SYSTEM_COLOR_KEYS, ...custom];
|
|
808
851
|
}
|
|
809
852
|
/**
|
|
@@ -813,7 +856,7 @@ function themeColorKeys(doc) {
|
|
|
813
856
|
* has `key`.
|
|
814
857
|
*/
|
|
815
858
|
function deleteLibraryColor(doc, key, replacement) {
|
|
816
|
-
const library = [...doc.colors?.library
|
|
859
|
+
const library = [...Array.isArray(doc.colors?.library) ? doc.colors.library : []];
|
|
817
860
|
const index = library.findIndex((row) => row.key === key);
|
|
818
861
|
if (index === -1) throw new Error(`No custom color named ${JSON.stringify(key)}`);
|
|
819
862
|
library.splice(index, 1);
|
|
@@ -841,7 +884,7 @@ function slugify(value) {
|
|
|
841
884
|
*/
|
|
842
885
|
const LibraryField = ({ path, readOnly }) => {
|
|
843
886
|
const { value, setValue } = useField({ path });
|
|
844
|
-
const rows = value
|
|
887
|
+
const rows = Array.isArray(value) ? value : [];
|
|
845
888
|
const [adding, setAdding] = useState(false);
|
|
846
889
|
const [name, setName] = useState("");
|
|
847
890
|
const [hex, setHex] = useState("#E07A5F");
|
|
@@ -884,7 +927,7 @@ const LibraryField = ({ path, readOnly }) => {
|
|
|
884
927
|
/* @__PURE__ */ jsx("style", {
|
|
885
928
|
href: "bl-library",
|
|
886
929
|
precedence: "default",
|
|
887
|
-
children: CSS$
|
|
930
|
+
children: CSS$3
|
|
888
931
|
}),
|
|
889
932
|
/* @__PURE__ */ jsxs("div", {
|
|
890
933
|
className: "bl-library__head",
|
|
@@ -997,12 +1040,13 @@ const LibraryField = ({ path, readOnly }) => {
|
|
|
997
1040
|
]
|
|
998
1041
|
});
|
|
999
1042
|
};
|
|
1000
|
-
const CSS$
|
|
1043
|
+
const CSS$3 = `
|
|
1001
1044
|
.bl-library__head{display:flex;justify-content:space-between;gap:1rem;align-items:flex-start;margin-bottom:.85rem}
|
|
1002
1045
|
.bl-library__head h2{margin:0;font-size:1.1rem}
|
|
1003
1046
|
.bl-library__head p{margin:.35rem 0 0;font-size:13px;color:var(--theme-elevation-500,#64748b)}
|
|
1004
1047
|
.bl-library__head button,.bl-library__add button,.bl-library__actions button{min-height:2.1rem;padding:.35rem .75rem;border-radius:8px;border:1px solid var(--theme-elevation-150,#e2e8f0);background:var(--theme-elevation-0,#fff);font:inherit;cursor:pointer}
|
|
1005
|
-
.bl-library__list{display:grid;gap:.85rem}
|
|
1048
|
+
.bl-library__list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.85rem}
|
|
1049
|
+
@media (max-width:860px){.bl-library__list{grid-template-columns:1fr}}
|
|
1006
1050
|
.bl-library__add{display:flex;flex-wrap:wrap;gap:.6rem;align-items:end;margin-bottom:.85rem;padding:.85rem;border:1px solid var(--theme-elevation-150,#e2e8f0);border-radius:12px}
|
|
1007
1051
|
.bl-library__add label{display:flex;flex-direction:column;gap:.3rem;font-size:12px;font-weight:600}
|
|
1008
1052
|
.bl-library__add input{min-height:2.1rem;padding:.3rem .55rem;border:1px solid var(--theme-elevation-150,#e2e8f0);border-radius:8px}
|
|
@@ -1217,7 +1261,7 @@ const FontField = ({ field, path, readOnly }) => {
|
|
|
1217
1261
|
/* @__PURE__ */ jsx("style", {
|
|
1218
1262
|
href: "bl-font-field",
|
|
1219
1263
|
precedence: "default",
|
|
1220
|
-
children: CSS$
|
|
1264
|
+
children: CSS$2
|
|
1221
1265
|
}),
|
|
1222
1266
|
faceIds.length > 0 ? /* @__PURE__ */ jsx("style", {
|
|
1223
1267
|
"data-bl-font-faces": "",
|
|
@@ -1343,7 +1387,7 @@ const FontField = ({ field, path, readOnly }) => {
|
|
|
1343
1387
|
]
|
|
1344
1388
|
});
|
|
1345
1389
|
};
|
|
1346
|
-
const CSS$
|
|
1390
|
+
const CSS$2 = `
|
|
1347
1391
|
.bl-font-field{margin-bottom:1rem}
|
|
1348
1392
|
.bl-font-field .field-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
|
1349
1393
|
.bl-font-field__trigger{display:flex;align-items:center;justify-content:space-between;width:100%;margin-top:1rem;min-height:3.25rem;padding:.7rem 1rem;border:1px solid var(--theme-elevation-150,#e2e8f0);border-radius:12px;background:var(--theme-input-bg,#fff);color:inherit;font:inherit;text-align:left;cursor:pointer}
|
|
@@ -1690,57 +1734,12 @@ const GREY_SCALE_FIELD_CSS = `
|
|
|
1690
1734
|
`;
|
|
1691
1735
|
//#endregion
|
|
1692
1736
|
//#region src/admin/contrast-report.tsx
|
|
1693
|
-
function hexAt(fields, path) {
|
|
1694
|
-
const value = fields[path]?.value;
|
|
1695
|
-
return typeof value === "string" ? value : "";
|
|
1696
|
-
}
|
|
1697
1737
|
/**
|
|
1698
|
-
*
|
|
1699
|
-
*
|
|
1738
|
+
* Contrast used to be a Colors-tab list. Readability now lives on each
|
|
1739
|
+
* color card: Needs attention opens a popup. This field stays in the
|
|
1740
|
+
* schema so `contrastTarget` is still a Theme option; it paints nothing.
|
|
1700
1741
|
*/
|
|
1701
|
-
const ContrastReport = (
|
|
1702
|
-
const target = Number((field.admin?.custom)?.target) || 7;
|
|
1703
|
-
const hexes = useFormFields(([fields]) => {
|
|
1704
|
-
const record = fields;
|
|
1705
|
-
const system = Object.fromEntries(SYSTEM_COLOR_KEYS.map((key) => [key, hexAt(record, `colors.brand.${key}.hex`)]));
|
|
1706
|
-
const library = record["colors.library"]?.value;
|
|
1707
|
-
return {
|
|
1708
|
-
system,
|
|
1709
|
-
custom: Array.isArray(library) ? library.flatMap((row, index) => {
|
|
1710
|
-
const hex = typeof row === "object" && row && "hex" in row ? String(row.hex ?? "") : "";
|
|
1711
|
-
const name = typeof row === "object" && row && "label" in row ? String(row.label ?? row.key ?? "Custom") : "Custom";
|
|
1712
|
-
return hex ? [{
|
|
1713
|
-
id: `library-${index}`,
|
|
1714
|
-
name,
|
|
1715
|
-
hex
|
|
1716
|
-
}] : [];
|
|
1717
|
-
}) : []
|
|
1718
|
-
};
|
|
1719
|
-
});
|
|
1720
|
-
const last = useRef(null);
|
|
1721
|
-
const complete = SYSTEM_COLOR_KEYS.every((key) => isThemeHex(hexes.system[key]));
|
|
1722
|
-
if (complete) last.current = [...SYSTEM_COLOR_KEYS.map((key) => fillLabelWarning(key, SYSTEM_COLOR_COPY[key].label, hexes.system[key], target)), ...hexes.custom.map((row) => fillLabelWarning(row.id, row.name, row.hex, target))].filter((item) => item !== null);
|
|
1723
|
-
const warnings = last.current ?? [];
|
|
1724
|
-
const stale = Boolean(last.current) && !complete;
|
|
1725
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1726
|
-
className: "field-type bl-contrast-report",
|
|
1727
|
-
children: [
|
|
1728
|
-
/* @__PURE__ */ jsx("style", {
|
|
1729
|
-
href: "bl-readability",
|
|
1730
|
-
precedence: "default",
|
|
1731
|
-
children: READABILITY_LIST_CSS
|
|
1732
|
-
}),
|
|
1733
|
-
stale ? /* @__PURE__ */ jsx("p", {
|
|
1734
|
-
className: "bl-contrast-report__stale",
|
|
1735
|
-
children: "Showing the last complete audit while a colour is being typed."
|
|
1736
|
-
}) : null,
|
|
1737
|
-
warnings.length > 0 ? /* @__PURE__ */ jsx(ReadabilityList, {
|
|
1738
|
-
warnings,
|
|
1739
|
-
target
|
|
1740
|
-
}) : /* @__PURE__ */ jsx("p", { children: "Enter hex colours to measure the automatic label on each fill." })
|
|
1741
|
-
]
|
|
1742
|
-
});
|
|
1743
|
-
};
|
|
1742
|
+
const ContrastReport = () => null;
|
|
1744
1743
|
//#endregion
|
|
1745
1744
|
//#region src/admin/section-heading.tsx
|
|
1746
1745
|
/**
|
|
@@ -1755,14 +1754,14 @@ const SectionHeading = ({ field }) => {
|
|
|
1755
1754
|
/* @__PURE__ */ jsx("style", {
|
|
1756
1755
|
href: "bl-section-heading",
|
|
1757
1756
|
precedence: "default",
|
|
1758
|
-
children: CSS
|
|
1757
|
+
children: CSS$1
|
|
1759
1758
|
}),
|
|
1760
1759
|
/* @__PURE__ */ jsx("h2", { children: custom.title }),
|
|
1761
1760
|
custom.hint ? /* @__PURE__ */ jsx("p", { children: custom.hint }) : null
|
|
1762
1761
|
]
|
|
1763
1762
|
});
|
|
1764
1763
|
};
|
|
1765
|
-
const CSS = `
|
|
1764
|
+
const CSS$1 = `
|
|
1766
1765
|
.bl-section-heading{margin:1.25rem 0 .65rem}
|
|
1767
1766
|
.bl-section-heading:first-child{margin-top:0}
|
|
1768
1767
|
.bl-section-heading h2{margin:0;font-size:1.1rem}
|
|
@@ -1770,6 +1769,10 @@ const CSS = `
|
|
|
1770
1769
|
`;
|
|
1771
1770
|
//#endregion
|
|
1772
1771
|
//#region src/theme/changes.ts
|
|
1772
|
+
/** Payload may hand an empty array field as `{}`. `.map` on that crashes the Theme form. */
|
|
1773
|
+
function libraryRows(value) {
|
|
1774
|
+
return Array.isArray(value) ? value : [];
|
|
1775
|
+
}
|
|
1773
1776
|
function colorLine(name, before, after) {
|
|
1774
1777
|
const a = before && typeof before === "object" ? before : { hex: before };
|
|
1775
1778
|
const b = after && typeof after === "object" ? after : { hex: after };
|
|
@@ -1789,8 +1792,8 @@ function themeChildChanges(child, published, incoming) {
|
|
|
1789
1792
|
const line = colorLine(key[0].toUpperCase() + key.slice(1), published.colors?.brand?.[key], incoming.colors?.brand?.[key]);
|
|
1790
1793
|
if (line) lines.push(line);
|
|
1791
1794
|
}
|
|
1792
|
-
const beforeKeys = (published.colors?.library
|
|
1793
|
-
const afterKeys = (incoming.colors?.library
|
|
1795
|
+
const beforeKeys = libraryRows(published.colors?.library).map((row) => row.key).join(", ");
|
|
1796
|
+
const afterKeys = libraryRows(incoming.colors?.library).map((row) => row.key).join(", ");
|
|
1794
1797
|
if (beforeKeys !== afterKeys) lines.push(`Custom colors: ${beforeKeys || "none"} → ${afterKeys || "none"}`);
|
|
1795
1798
|
if ((published.colors?.greyScale ?? "") !== (incoming.colors?.greyScale ?? "")) lines.push(`Gray family: ${published.colors?.greyScale ?? "—"} → ${incoming.colors?.greyScale ?? "—"}`);
|
|
1796
1799
|
return lines;
|
|
@@ -1924,13 +1927,24 @@ const PUBLISH_CONFIRM_CSS = `
|
|
|
1924
1927
|
.bl-publish__actions button:disabled{opacity:.45;cursor:not-allowed}
|
|
1925
1928
|
`;
|
|
1926
1929
|
//#endregion
|
|
1927
|
-
//#region src/admin/
|
|
1928
|
-
const
|
|
1930
|
+
//#region src/admin/theme-tab.ts
|
|
1931
|
+
const THEME_TAB_LABELS = {
|
|
1929
1932
|
colors: "Colors",
|
|
1930
1933
|
typography: "Typography",
|
|
1931
1934
|
appearance: "Appearance",
|
|
1932
1935
|
identity: "Identity"
|
|
1933
1936
|
};
|
|
1937
|
+
/**
|
|
1938
|
+
* The selected Payload field tab on Theme. Defaults to Colors when the
|
|
1939
|
+
* tabs have not painted yet (SSR, first paint).
|
|
1940
|
+
*/
|
|
1941
|
+
function readActiveThemeTab(root = typeof document === "undefined" ? null : document) {
|
|
1942
|
+
if (!root) return "colors";
|
|
1943
|
+
const text = (root.querySelector(".tabs-field__tab-button[aria-selected=\"true\"]") ?? root.querySelector(".tabs-field__tab-button--active") ?? root.querySelector("[role=\"tab\"][aria-selected=\"true\"]"))?.textContent?.replace(/\s+/g, " ").trim();
|
|
1944
|
+
return THEME_CHILDREN.find((id) => THEME_TAB_LABELS[id] === text) ?? "colors";
|
|
1945
|
+
}
|
|
1946
|
+
//#endregion
|
|
1947
|
+
//#region src/admin/publish-child.tsx
|
|
1934
1948
|
function asColor(value) {
|
|
1935
1949
|
if (value && typeof value === "object") return value;
|
|
1936
1950
|
if (typeof value === "string") return { hex: value };
|
|
@@ -1942,7 +1956,7 @@ function formDoc(fields) {
|
|
|
1942
1956
|
hex: fields[`colors.brand.${key}.hex`]?.value,
|
|
1943
1957
|
sourceStep: fields[`colors.brand.${key}.sourceStep`]?.value
|
|
1944
1958
|
}])),
|
|
1945
|
-
library: fields["colors.library"]?.value
|
|
1959
|
+
library: libraryRows(fields["colors.library"]?.value),
|
|
1946
1960
|
greyScale: fields["colors.greyScale"]?.value
|
|
1947
1961
|
},
|
|
1948
1962
|
typography: {
|
|
@@ -1966,7 +1980,7 @@ function publishedDoc(fields) {
|
|
|
1966
1980
|
}
|
|
1967
1981
|
function shortsFrom(doc) {
|
|
1968
1982
|
const brand = doc.colors?.brand ?? {};
|
|
1969
|
-
const custom = doc.colors?.library
|
|
1983
|
+
const custom = libraryRows(doc.colors?.library);
|
|
1970
1984
|
return [...SYSTEM_COLOR_KEYS.flatMap((key) => {
|
|
1971
1985
|
const hex = asColor(brand[key])?.hex;
|
|
1972
1986
|
const warning = typeof hex === "string" ? fillLabelWarning(key, SYSTEM_COLOR_COPY[key].label, hex) : null;
|
|
@@ -1977,13 +1991,12 @@ function shortsFrom(doc) {
|
|
|
1977
1991
|
})];
|
|
1978
1992
|
}
|
|
1979
1993
|
/**
|
|
1980
|
-
*
|
|
1981
|
-
*
|
|
1982
|
-
*
|
|
1994
|
+
* Publish for the open Theme tab. Lives in Payload's document Save
|
|
1995
|
+
* slot (`ThemeSaveButton`) so the header matches a Pages document.
|
|
1996
|
+
* Sets `publishChild` then submits; `beforeChange` writes only that slice.
|
|
1983
1997
|
*/
|
|
1984
|
-
|
|
1985
|
-
const
|
|
1986
|
-
const label = isThemeChild(child) ? LABELS[child] : "Theme";
|
|
1998
|
+
function ThemePublishControls({ child }) {
|
|
1999
|
+
const label = THEME_TAB_LABELS[child];
|
|
1987
2000
|
const { submit } = useForm();
|
|
1988
2001
|
const publishChild = useField({ path: "publishChild" });
|
|
1989
2002
|
const snapshot = useFormFields(([fields]) => {
|
|
@@ -1995,10 +2008,9 @@ const PublishChild = ({ field }) => {
|
|
|
1995
2008
|
});
|
|
1996
2009
|
const [open, setOpen] = useState(false);
|
|
1997
2010
|
const [busy, setBusy] = useState(false);
|
|
1998
|
-
const changes = useMemo(() =>
|
|
2011
|
+
const changes = useMemo(() => themeChildChanges(child, snapshot.published, snapshot.incoming), [child, snapshot]);
|
|
1999
2012
|
const shorts = child === "colors" ? shortsFrom(snapshot.incoming) : void 0;
|
|
2000
2013
|
async function publish() {
|
|
2001
|
-
if (!isThemeChild(child)) return;
|
|
2002
2014
|
setBusy(true);
|
|
2003
2015
|
publishChild.setValue(child);
|
|
2004
2016
|
try {
|
|
@@ -2009,7 +2021,7 @@ const PublishChild = ({ field }) => {
|
|
|
2009
2021
|
}
|
|
2010
2022
|
}
|
|
2011
2023
|
return /* @__PURE__ */ jsxs("div", {
|
|
2012
|
-
className: "
|
|
2024
|
+
className: "bl-publish-child",
|
|
2013
2025
|
children: [
|
|
2014
2026
|
/* @__PURE__ */ jsx("style", {
|
|
2015
2027
|
href: "bl-publish",
|
|
@@ -2019,7 +2031,7 @@ const PublishChild = ({ field }) => {
|
|
|
2019
2031
|
/* @__PURE__ */ jsx("style", {
|
|
2020
2032
|
href: "bl-publish-child",
|
|
2021
2033
|
precedence: "default",
|
|
2022
|
-
children: `${THEME_PREVIEW_TOGGLE_CSS}.bl-publish-child{
|
|
2034
|
+
children: `${THEME_PREVIEW_TOGGLE_CSS}.bl-publish-child{display:flex;align-items:center;gap:.75rem}.bl-publish-child__button{min-height:2.25rem;padding:.4rem 1rem;border:0;border-radius:8px;background:#a80063;color:#fff;font:inherit;font-weight:600;cursor:pointer}`
|
|
2023
2035
|
}),
|
|
2024
2036
|
child === "colors" ? /* @__PURE__ */ jsx(ThemePreviewToggle, {}) : null,
|
|
2025
2037
|
/* @__PURE__ */ jsxs("button", {
|
|
@@ -2040,17 +2052,81 @@ const PublishChild = ({ field }) => {
|
|
|
2040
2052
|
}) : null
|
|
2041
2053
|
]
|
|
2042
2054
|
});
|
|
2055
|
+
}
|
|
2056
|
+
/** @deprecated Theme publish is the document Save button */
|
|
2057
|
+
const PublishChild = ({ field }) => {
|
|
2058
|
+
const child = (field.admin?.custom)?.child;
|
|
2059
|
+
return /* @__PURE__ */ jsx(ThemePublishControls, { child: isThemeChild(child) ? child : "colors" });
|
|
2043
2060
|
};
|
|
2044
2061
|
//#endregion
|
|
2045
2062
|
//#region src/admin/save-button.tsx
|
|
2046
2063
|
/**
|
|
2047
|
-
*
|
|
2048
|
-
*
|
|
2064
|
+
* Payload's document Save slot — the same control row as Pages'
|
|
2065
|
+
* "Publish changes". Theme has no drafts; this publishes only the
|
|
2066
|
+
* open field tab. The tab is read after mount so SSR matches.
|
|
2049
2067
|
*/
|
|
2050
|
-
function
|
|
2051
|
-
|
|
2068
|
+
function ThemeSaveButton() {
|
|
2069
|
+
const [child, setChild] = useState("colors");
|
|
2070
|
+
useEffect(() => {
|
|
2071
|
+
const sync = () => setChild(readActiveThemeTab());
|
|
2072
|
+
sync();
|
|
2073
|
+
const target = document.querySelector(".tabs-field") ?? document.body;
|
|
2074
|
+
const observer = new MutationObserver(sync);
|
|
2075
|
+
observer.observe(target, {
|
|
2076
|
+
subtree: true,
|
|
2077
|
+
attributes: true,
|
|
2078
|
+
attributeFilter: ["aria-selected", "class"],
|
|
2079
|
+
childList: true
|
|
2080
|
+
});
|
|
2081
|
+
target.addEventListener("click", sync);
|
|
2082
|
+
return () => {
|
|
2083
|
+
observer.disconnect();
|
|
2084
|
+
target.removeEventListener("click", sync);
|
|
2085
|
+
};
|
|
2086
|
+
}, []);
|
|
2087
|
+
return /* @__PURE__ */ jsx(ThemePublishControls, { child });
|
|
2052
2088
|
}
|
|
2089
|
+
/** Import-map alias — Theme still points `SaveButton` at this name. */
|
|
2090
|
+
const HiddenSaveButton = ThemeSaveButton;
|
|
2091
|
+
//#endregion
|
|
2092
|
+
//#region src/admin/identity-fallback.tsx
|
|
2093
|
+
/**
|
|
2094
|
+
* Identity child when the site has not registered a cupboard yet.
|
|
2095
|
+
* Shows the fallback lockup and mark; uploads wait on `logo.collection`.
|
|
2096
|
+
*/
|
|
2097
|
+
const IdentityFallback = ({ field }) => {
|
|
2098
|
+
const fallback = (field.admin?.custom)?.fallback;
|
|
2099
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
2100
|
+
className: "bl-identity-fallback",
|
|
2101
|
+
children: [
|
|
2102
|
+
/* @__PURE__ */ jsx("style", {
|
|
2103
|
+
href: "bl-identity-fallback",
|
|
2104
|
+
precedence: "default",
|
|
2105
|
+
children: CSS
|
|
2106
|
+
}),
|
|
2107
|
+
/* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsx("h2", { children: "Site identity" }), /* @__PURE__ */ jsx("p", { children: "Today's lockup and mark until a brand editor uploads replacements." })] }),
|
|
2108
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2109
|
+
className: "bl-identity-fallback__grid",
|
|
2110
|
+
children: [fallback?.lockup ? /* @__PURE__ */ jsxs("figure", { children: [/* @__PURE__ */ jsx("img", {
|
|
2111
|
+
src: fallback.lockup.url,
|
|
2112
|
+
alt: fallback.lockup.alt
|
|
2113
|
+
}), /* @__PURE__ */ jsx("figcaption", { children: "Lockup" })] }) : null, fallback?.mark ? /* @__PURE__ */ jsxs("figure", { children: [/* @__PURE__ */ jsx("img", {
|
|
2114
|
+
src: fallback.mark.url,
|
|
2115
|
+
alt: fallback.mark.alt
|
|
2116
|
+
}), /* @__PURE__ */ jsx("figcaption", { children: "Mark" })] }) : null]
|
|
2117
|
+
})
|
|
2118
|
+
]
|
|
2119
|
+
});
|
|
2120
|
+
};
|
|
2121
|
+
const CSS = `
|
|
2122
|
+
.bl-identity-fallback header h2{margin:0;font-size:1.1rem}
|
|
2123
|
+
.bl-identity-fallback header p{margin:.35rem 0 1rem;color:var(--theme-elevation-600,#475569)}
|
|
2124
|
+
.bl-identity-fallback__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(12rem,1fr));gap:1rem}
|
|
2125
|
+
.bl-identity-fallback figure{margin:0;padding:1rem;border:1px solid var(--theme-elevation-150,#e2e8f0);border-radius:10px;background:var(--theme-elevation-50,#f8fafc)}
|
|
2126
|
+
.bl-identity-fallback img{display:block;max-width:100%;height:4rem;object-fit:contain}
|
|
2127
|
+
.bl-identity-fallback figcaption{margin-top:.5rem;font-size:.8rem;color:var(--theme-elevation-600,#475569)}
|
|
2128
|
+
`;
|
|
2053
2129
|
//#endregion
|
|
2054
|
-
export { AppearanceField, ColorField, ColorScaleField, ContrastReport, FontField, GreyScaleField, HiddenSaveButton, LibraryField, PairingField, PublishChild, SectionHeading };
|
|
2130
|
+
export { AppearanceField, ColorField, ColorScaleField, ContrastReport, FontField, GreyScaleField, HiddenSaveButton, IdentityFallback, LibraryField, PairingField, PublishChild, SectionHeading, ThemeSaveButton };
|
|
2055
2131
|
|
|
2056
2132
|
//# sourceMappingURL=admin.mjs.map
|