@bison-lab/payload-core 3.21.0 → 3.24.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 +10 -8
- package/dist/admin.d.mts +9 -5
- package/dist/admin.d.mts.map +1 -1
- package/dist/admin.mjs +395 -321
- package/dist/admin.mjs.map +1 -1
- package/dist/index.d.mts +23 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +101 -75
- package/dist/index.mjs.map +1 -1
- package/dist/navigation.d.mts +1 -1
- package/dist/navigation.mjs +1 -1
- package/dist/{published-qFPVvTk_.d.mts → published-BtEiv0lH.d.mts} +3 -3
- package/dist/{published-qFPVvTk_.d.mts.map → published-BtEiv0lH.d.mts.map} +1 -1
- package/dist/{published-CFYwqnZI.mjs → published-Chd5PFhw.mjs} +3 -3
- package/dist/published-Chd5PFhw.mjs.map +1 -0
- package/package.json +7 -3
- package/dist/published-CFYwqnZI.mjs.map +0 -1
package/dist/admin.mjs
CHANGED
|
@@ -4,6 +4,8 @@ import { ArrayField, Button, CheckboxInput, FieldDescription, FieldError, FieldL
|
|
|
4
4
|
import { GREY_SCALES, SHADE_STEPS, contrastForeground, contrastRatio, createColorScale, deriveDarkPalette, deriveLightPalette, hexToHSL, hslToString, includedShadeSteps, isThemeHex, presetHints, setColorScaleInclude } from "@bison-lab/tokens";
|
|
5
5
|
import { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { Badge, Dialog, Field, Input, KitProvider, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@bison-lab/admin-ui";
|
|
8
|
+
import { HexColorPicker } from "react-colorful";
|
|
7
9
|
import { createPortal } from "react-dom";
|
|
8
10
|
import { findFont, fontFaceCss, isFontId } from "@bison-lab/fonts";
|
|
9
11
|
//#region src/admin/color-field.tsx
|
|
@@ -41,7 +43,7 @@ const ColorField = ({ field, path, readOnly }) => {
|
|
|
41
43
|
/* @__PURE__ */ jsx("style", {
|
|
42
44
|
href: "bl-color-field",
|
|
43
45
|
precedence: "default",
|
|
44
|
-
children: CSS$
|
|
46
|
+
children: CSS$5
|
|
45
47
|
}),
|
|
46
48
|
/* @__PURE__ */ jsx(FieldLabel, {
|
|
47
49
|
htmlFor: hexId,
|
|
@@ -100,7 +102,7 @@ const ColorField = ({ field, path, readOnly }) => {
|
|
|
100
102
|
]
|
|
101
103
|
});
|
|
102
104
|
};
|
|
103
|
-
const CSS$
|
|
105
|
+
const CSS$5 = `
|
|
104
106
|
.bl-color-field__control{display:flex;align-items:center;gap:calc(var(--base) * .4)}
|
|
105
107
|
.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)}
|
|
106
108
|
.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}
|
|
@@ -345,6 +347,123 @@ function readabilityRatioLine(sample, target = 7) {
|
|
|
345
347
|
const READABILITY_FIX = "Darken or lighten the hex, then regenerate the scale. The site picks light or dark type for you.";
|
|
346
348
|
const READABILITY_PUBLISH_NOTE = "You can still publish. To improve a color, darken or lighten it and regenerate.";
|
|
347
349
|
//#endregion
|
|
350
|
+
//#region src/admin/portal.tsx
|
|
351
|
+
/** Theme overlays must leave Payload's transformed/clipped admin tree. */
|
|
352
|
+
function ThemePortal({ children }) {
|
|
353
|
+
if (typeof document === "undefined") return null;
|
|
354
|
+
return createPortal(children, document.body);
|
|
355
|
+
}
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/admin/brand-hex-field.tsx
|
|
358
|
+
/** Keep a leading # and at most six hex digits. Drop everything else. */
|
|
359
|
+
function filterThemeHexInput(raw) {
|
|
360
|
+
const trimmed = raw.trim();
|
|
361
|
+
if (trimmed === "") return "";
|
|
362
|
+
return `#${trimmed.replace(/^#/, "").replace(/[^0-9a-fA-F]/g, "").slice(0, 6)}`;
|
|
363
|
+
}
|
|
364
|
+
function BrandHexField({ name, value, onChange, readOnly, placeholder = "#DB0082", picker = "dialog" }) {
|
|
365
|
+
const [draft, setDraft] = useState(value);
|
|
366
|
+
const [open, setOpen] = useState(false);
|
|
367
|
+
const [pickerDraft, setPickerDraft] = useState(value);
|
|
368
|
+
useEffect(() => {
|
|
369
|
+
setDraft(value);
|
|
370
|
+
}, [value]);
|
|
371
|
+
function typeHex(next) {
|
|
372
|
+
const filtered = filterThemeHexInput(next);
|
|
373
|
+
setDraft(filtered);
|
|
374
|
+
if (isThemeHex(filtered)) onChange(filtered);
|
|
375
|
+
}
|
|
376
|
+
function openPicker() {
|
|
377
|
+
setPickerDraft(isThemeHex(draft) ? draft : value);
|
|
378
|
+
setOpen(true);
|
|
379
|
+
}
|
|
380
|
+
function applyPicker() {
|
|
381
|
+
if (!isThemeHex(pickerDraft)) return;
|
|
382
|
+
onChange(pickerDraft);
|
|
383
|
+
setDraft(pickerDraft);
|
|
384
|
+
setOpen(false);
|
|
385
|
+
}
|
|
386
|
+
const input = /* @__PURE__ */ jsx(Input, {
|
|
387
|
+
"aria-label": `${name} hex`,
|
|
388
|
+
value: draft,
|
|
389
|
+
placeholder,
|
|
390
|
+
spellCheck: false,
|
|
391
|
+
autoComplete: "off",
|
|
392
|
+
disabled: readOnly,
|
|
393
|
+
onChange: (event) => typeHex(event.target.value),
|
|
394
|
+
onBlur: () => {
|
|
395
|
+
if (!isThemeHex(draft)) setDraft(value);
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
return /* @__PURE__ */ jsxs(KitProvider, { children: [
|
|
399
|
+
/* @__PURE__ */ jsx("style", {
|
|
400
|
+
href: "bl-brand-hex",
|
|
401
|
+
precedence: "default",
|
|
402
|
+
children: CSS$4
|
|
403
|
+
}),
|
|
404
|
+
picker === "inline" ? /* @__PURE__ */ jsxs("div", {
|
|
405
|
+
className: "bl-brand-hex bl-brand-hex--inline",
|
|
406
|
+
children: [/* @__PURE__ */ jsx(HexColorPicker, {
|
|
407
|
+
color: isThemeHex(draft) ? draft : "#000000",
|
|
408
|
+
onChange: (hex) => {
|
|
409
|
+
setDraft(hex);
|
|
410
|
+
onChange(hex);
|
|
411
|
+
}
|
|
412
|
+
}), /* @__PURE__ */ jsxs(Field, {
|
|
413
|
+
as: "div",
|
|
414
|
+
children: [/* @__PURE__ */ jsx(Label, { children: "Hex" }), input]
|
|
415
|
+
})]
|
|
416
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
417
|
+
className: "bl-brand-hex",
|
|
418
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
419
|
+
type: "button",
|
|
420
|
+
className: "bl-brand-hex__swatch",
|
|
421
|
+
"aria-label": `${name} picker`,
|
|
422
|
+
disabled: readOnly,
|
|
423
|
+
style: { background: isThemeHex(draft) ? draft : "transparent" },
|
|
424
|
+
onClick: openPicker
|
|
425
|
+
}), input]
|
|
426
|
+
}),
|
|
427
|
+
picker === "dialog" ? /* @__PURE__ */ jsx(ThemePortal, { children: /* @__PURE__ */ jsx("div", {
|
|
428
|
+
className: "bl-theme-dialog",
|
|
429
|
+
children: /* @__PURE__ */ jsx(Dialog, {
|
|
430
|
+
open,
|
|
431
|
+
title: `Pick ${name}`,
|
|
432
|
+
onCancel: () => setOpen(false),
|
|
433
|
+
confirmLabel: "Apply",
|
|
434
|
+
onConfirm: applyPicker,
|
|
435
|
+
confirmDisabled: !isThemeHex(pickerDraft),
|
|
436
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
437
|
+
className: "bl-brand-hex bl-brand-hex--inline",
|
|
438
|
+
children: [/* @__PURE__ */ jsx(HexColorPicker, {
|
|
439
|
+
color: isThemeHex(pickerDraft) ? pickerDraft : "#000000",
|
|
440
|
+
onChange: setPickerDraft
|
|
441
|
+
}), /* @__PURE__ */ jsxs(Field, {
|
|
442
|
+
as: "div",
|
|
443
|
+
children: [/* @__PURE__ */ jsx(Label, { children: "Hex" }), /* @__PURE__ */ jsx(Input, {
|
|
444
|
+
"aria-label": `${name} picker hex`,
|
|
445
|
+
value: pickerDraft,
|
|
446
|
+
placeholder,
|
|
447
|
+
spellCheck: false,
|
|
448
|
+
autoComplete: "off",
|
|
449
|
+
onChange: (event) => setPickerDraft(filterThemeHexInput(event.target.value))
|
|
450
|
+
})]
|
|
451
|
+
})]
|
|
452
|
+
})
|
|
453
|
+
})
|
|
454
|
+
}) }) : null
|
|
455
|
+
] });
|
|
456
|
+
}
|
|
457
|
+
const CSS$4 = `
|
|
458
|
+
.bl-brand-hex{display:flex;align-items:stretch;gap:8px;min-width:0}
|
|
459
|
+
.bl-brand-hex--inline{flex-direction:column;gap:12px}
|
|
460
|
+
.bl-brand-hex .react-colorful{width:100%;height:200px}
|
|
461
|
+
.bl-brand-hex__swatch{flex:none;width:38px;border:1px solid #3a3d46;border-radius:8px;padding:0;cursor:pointer;background:#1d1f24}
|
|
462
|
+
.bl-brand-hex__swatch:disabled{opacity:.5;cursor:not-allowed}
|
|
463
|
+
.bl-brand-hex .bl-nav-kit__input{font-family:var(--font-mono,ui-monospace,monospace)}
|
|
464
|
+
.bl-theme-dialog .bl-nav-kit__modal{z-index:10000}
|
|
465
|
+
`;
|
|
466
|
+
//#endregion
|
|
348
467
|
//#region src/admin/colors-layout.ts
|
|
349
468
|
/**
|
|
350
469
|
* Theme Colors tab chrome. Payload group-in-group draws a left gutter;
|
|
@@ -386,13 +505,6 @@ const THEME_COLORS_LAYOUT_CSS = `
|
|
|
386
505
|
}
|
|
387
506
|
`;
|
|
388
507
|
//#endregion
|
|
389
|
-
//#region src/admin/portal.tsx
|
|
390
|
-
/** Theme overlays must leave Payload's transformed/clipped admin tree. */
|
|
391
|
-
function ThemePortal({ children }) {
|
|
392
|
-
if (typeof document === "undefined") return null;
|
|
393
|
-
return createPortal(children, document.body);
|
|
394
|
-
}
|
|
395
|
-
//#endregion
|
|
396
508
|
//#region src/admin/preview-mode.tsx
|
|
397
509
|
const ATTR = "data-bl-theme-preview";
|
|
398
510
|
const EVENT = "bl-theme-preview";
|
|
@@ -410,7 +522,11 @@ const PREVIEW_BRAND = {
|
|
|
410
522
|
secondary: "#111111",
|
|
411
523
|
success: "#111111"
|
|
412
524
|
};
|
|
413
|
-
|
|
525
|
+
function readDocumentTheme() {
|
|
526
|
+
if (typeof document === "undefined") return "light";
|
|
527
|
+
return document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light";
|
|
528
|
+
}
|
|
529
|
+
let currentMode = readDocumentTheme();
|
|
414
530
|
function readMode() {
|
|
415
531
|
return currentMode;
|
|
416
532
|
}
|
|
@@ -450,7 +566,10 @@ function previewVarsFor(grey, mode) {
|
|
|
450
566
|
"--bl-preview-border": `hsl(${palette.border})`,
|
|
451
567
|
"--bl-preview-text": `hsl(${palette.foreground})`,
|
|
452
568
|
"--bl-preview-muted": `hsl(${palette["muted-foreground"]})`,
|
|
453
|
-
"--bl-preview-input": `hsl(${palette.input})
|
|
569
|
+
"--bl-preview-input": `hsl(${palette.input})`,
|
|
570
|
+
"--theme-elevation-0": `hsl(${palette.card})`,
|
|
571
|
+
"--theme-elevation-150": `hsl(${palette.border})`,
|
|
572
|
+
"--theme-elevation-800": `hsl(${palette.foreground})`
|
|
454
573
|
};
|
|
455
574
|
}
|
|
456
575
|
function useGreyScale() {
|
|
@@ -471,30 +590,6 @@ function usePreviewCanvas() {
|
|
|
471
590
|
style: previewVarsFor(useGreyScale(), mode)
|
|
472
591
|
};
|
|
473
592
|
}
|
|
474
|
-
function ThemePreviewToggle() {
|
|
475
|
-
const mode = useThemePreviewMode();
|
|
476
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
477
|
-
className: "bl-preview-toggle",
|
|
478
|
-
role: "group",
|
|
479
|
-
"aria-label": "Preview theme in",
|
|
480
|
-
children: [/* @__PURE__ */ jsx("button", {
|
|
481
|
-
type: "button",
|
|
482
|
-
"data-on": mode === "light" ? "" : void 0,
|
|
483
|
-
onClick: () => setThemePreviewMode("light"),
|
|
484
|
-
children: "Light"
|
|
485
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
486
|
-
type: "button",
|
|
487
|
-
"data-on": mode === "dark" ? "" : void 0,
|
|
488
|
-
onClick: () => setThemePreviewMode("dark"),
|
|
489
|
-
children: "Dark"
|
|
490
|
-
})]
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
const THEME_PREVIEW_TOGGLE_CSS = `
|
|
494
|
-
.bl-preview-toggle{display:inline-flex;padding:3px;border:1px solid var(--theme-elevation-150,#e2e8f0);border-radius:10px;background:var(--theme-elevation-0,#fff)}
|
|
495
|
-
.bl-preview-toggle button{min-height:2rem;padding:.25rem .75rem;border:0;border-radius:7px;background:transparent;color:var(--theme-elevation-600,#475569);font:inherit;font-size:13px;font-weight:600;cursor:pointer}
|
|
496
|
-
.bl-preview-toggle button[data-on]{background:var(--theme-text,#0f172a);color:var(--theme-bg,#fff)}
|
|
497
|
-
`;
|
|
498
593
|
//#endregion
|
|
499
594
|
//#region src/admin/readability-list.tsx
|
|
500
595
|
function ReadabilityDetail({ item, target = 7 }) {
|
|
@@ -614,13 +709,9 @@ function ColorScaleCard({ id, name, hint, required, custom, state, onChange, onD
|
|
|
614
709
|
const canvas = usePreviewCanvas();
|
|
615
710
|
const [attentionOpen, setAttentionOpen] = useState(false);
|
|
616
711
|
const [shakeStep, setShakeStep] = useState(null);
|
|
617
|
-
const [hexDraft, setHexDraft] = useState(state.hex);
|
|
618
712
|
const titleId = useId();
|
|
619
713
|
const included = new Set(includedShadeSteps(state));
|
|
620
714
|
const hueDrift = role === "success" ? Boolean(successHueWarning(state.hex)) : role === "destructive" ? Boolean(destructiveHueWarning(state.hex)) : false;
|
|
621
|
-
useEffect(() => {
|
|
622
|
-
setHexDraft(state.hex);
|
|
623
|
-
}, [state.hex]);
|
|
624
715
|
function commitHex(hex) {
|
|
625
716
|
onChange(createColorScale(hex, state.sourceStep, state.include));
|
|
626
717
|
}
|
|
@@ -638,211 +729,182 @@ function ColorScaleCard({ id, name, hint, required, custom, state, onChange, onD
|
|
|
638
729
|
else next.add(step);
|
|
639
730
|
onChange(setColorScaleInclude(state, SHADE_STEPS.filter((item) => next.has(item))));
|
|
640
731
|
}
|
|
641
|
-
return /* @__PURE__ */
|
|
642
|
-
|
|
643
|
-
"
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
className: "bl-scale-
|
|
650
|
-
children: [
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
732
|
+
return /* @__PURE__ */ jsx(KitProvider, {
|
|
733
|
+
accent: id === "primary" && isThemeHex(state.hex) ? state.hex : void 0,
|
|
734
|
+
children: /* @__PURE__ */ jsxs("article", {
|
|
735
|
+
className: `bl-scale-card ${canvas.className}`,
|
|
736
|
+
"data-preview": canvas.mode,
|
|
737
|
+
style: canvas.style,
|
|
738
|
+
children: [
|
|
739
|
+
/* @__PURE__ */ jsxs("header", {
|
|
740
|
+
className: "bl-scale-card__head",
|
|
741
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
|
|
742
|
+
className: "bl-scale-card__title-row",
|
|
743
|
+
children: [
|
|
744
|
+
/* @__PURE__ */ jsx("h3", {
|
|
745
|
+
className: "bl-scale-card__title",
|
|
746
|
+
children: name
|
|
747
|
+
}),
|
|
748
|
+
required ? /* @__PURE__ */ jsx(Badge, { children: "Required" }) : null,
|
|
749
|
+
custom ? /* @__PURE__ */ jsx(Badge, { children: "Optional" }) : null,
|
|
750
|
+
warning && !warning.meets ? /* @__PURE__ */ jsx(Badge, {
|
|
751
|
+
as: "button",
|
|
752
|
+
variant: "danger",
|
|
753
|
+
"aria-haspopup": "dialog",
|
|
754
|
+
onClick: () => setAttentionOpen(true),
|
|
755
|
+
children: "Needs attention"
|
|
756
|
+
}) : null
|
|
757
|
+
]
|
|
758
|
+
}), hint ? /* @__PURE__ */ jsx("p", {
|
|
759
|
+
className: "bl-scale-card__hint",
|
|
760
|
+
children: hint
|
|
761
|
+
}) : null] }), onDelete ? /* @__PURE__ */ jsx("button", {
|
|
762
|
+
type: "button",
|
|
763
|
+
className: "bl-scale-card__delete",
|
|
764
|
+
disabled: readOnly,
|
|
765
|
+
onClick: onDelete,
|
|
766
|
+
children: "Delete"
|
|
767
|
+
}) : null]
|
|
768
|
+
}),
|
|
769
|
+
/* @__PURE__ */ jsxs("div", {
|
|
770
|
+
className: "bl-scale-card__row",
|
|
771
|
+
children: [/* @__PURE__ */ jsxs(Field, {
|
|
772
|
+
as: "div",
|
|
773
|
+
children: [/* @__PURE__ */ jsx(Label, { children: "Brand hex" }), /* @__PURE__ */ jsx(BrandHexField, {
|
|
774
|
+
name,
|
|
775
|
+
value: state.hex,
|
|
776
|
+
onChange: commitHex,
|
|
777
|
+
readOnly
|
|
778
|
+
})]
|
|
779
|
+
}), /* @__PURE__ */ jsxs(Field, {
|
|
780
|
+
as: "div",
|
|
781
|
+
children: [/* @__PURE__ */ jsx(Label, { children: "This color is" }), /* @__PURE__ */ jsxs(Select, {
|
|
782
|
+
value: String(state.sourceStep),
|
|
783
|
+
onValueChange: (value) => commitStep(Number(value)),
|
|
784
|
+
disabled: readOnly,
|
|
785
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
786
|
+
"aria-label": "This color is",
|
|
787
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
788
|
+
}), /* @__PURE__ */ jsx(SelectContent, { children: SHADE_STEPS.map((step) => /* @__PURE__ */ jsx(SelectItem, {
|
|
789
|
+
value: String(step),
|
|
790
|
+
children: step
|
|
791
|
+
}, step)) })]
|
|
792
|
+
})]
|
|
793
|
+
})]
|
|
794
|
+
}),
|
|
795
|
+
role ? /* @__PURE__ */ jsxs("div", {
|
|
796
|
+
className: "bl-scale-card__family",
|
|
797
|
+
"data-role": role,
|
|
798
|
+
"data-drift": hueDrift ? "" : void 0,
|
|
799
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
800
|
+
className: "bl-scale-card__family-mark",
|
|
801
|
+
"aria-hidden": "true",
|
|
802
|
+
children: "!"
|
|
803
|
+
}), /* @__PURE__ */ jsxs("div", { children: [
|
|
804
|
+
/* @__PURE__ */ jsx("div", {
|
|
805
|
+
className: "bl-scale-card__family-title",
|
|
806
|
+
children: STATUS_COPY[role].title
|
|
654
807
|
}),
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
custom ? /* @__PURE__ */ jsx("span", {
|
|
660
|
-
className: "bl-scale-card__badge",
|
|
661
|
-
children: "Optional"
|
|
662
|
-
}) : null,
|
|
663
|
-
warning && !warning.meets ? /* @__PURE__ */ jsx("button", {
|
|
664
|
-
type: "button",
|
|
665
|
-
className: "bl-scale-card__badge bl-scale-card__badge--attention",
|
|
666
|
-
"aria-haspopup": "dialog",
|
|
667
|
-
onClick: () => setAttentionOpen(true),
|
|
668
|
-
children: "Needs attention"
|
|
808
|
+
/* @__PURE__ */ jsx("p", { children: STATUS_COPY[role].body }),
|
|
809
|
+
hueDrift ? /* @__PURE__ */ jsx("p", {
|
|
810
|
+
className: "bl-scale-card__family-drift",
|
|
811
|
+
children: STATUS_COPY[role].drift
|
|
669
812
|
}) : null
|
|
670
|
-
]
|
|
671
|
-
})
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
type: "color",
|
|
690
|
-
"aria-label": `${name} picker`,
|
|
813
|
+
] })]
|
|
814
|
+
}) : null,
|
|
815
|
+
/* @__PURE__ */ jsxs("div", {
|
|
816
|
+
className: "bl-scale-card__scale-head",
|
|
817
|
+
children: [/* @__PURE__ */ jsx("span", { children: "Generated scale" }), /* @__PURE__ */ jsxs("span", { children: [SHADE_STEPS.length, " shades"] })]
|
|
818
|
+
}),
|
|
819
|
+
/* @__PURE__ */ jsx("div", {
|
|
820
|
+
className: "bl-scale-card__steps",
|
|
821
|
+
role: "group",
|
|
822
|
+
"aria-label": `${name} scale steps`,
|
|
823
|
+
children: SHADE_STEPS.map((step) => {
|
|
824
|
+
const source = step === state.sourceStep;
|
|
825
|
+
const on = included.has(step);
|
|
826
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
827
|
+
type: "button",
|
|
828
|
+
className: "bl-scale-card__step",
|
|
829
|
+
"data-source": source ? "" : void 0,
|
|
830
|
+
"data-excluded": on ? void 0 : "",
|
|
831
|
+
"data-shake": shakeStep === step ? "" : void 0,
|
|
691
832
|
disabled: readOnly,
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
833
|
+
"aria-pressed": on,
|
|
834
|
+
"aria-label": source ? `Source step ${step} cannot be excluded` : on ? `Shade ${step}, available — click to exclude from the palette` : `Shade ${step}, excluded — click to include in the palette`,
|
|
835
|
+
title: source ? `Source step ${step} cannot be excluded` : on ? "Available to page editors — click to exclude" : "Excluded from page editors — click to include",
|
|
836
|
+
onClick: (event) => {
|
|
696
837
|
event.preventDefault();
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
} catch {
|
|
700
|
-
input.click();
|
|
701
|
-
}
|
|
702
|
-
},
|
|
703
|
-
onChange: (event) => commitHex(event.target.value)
|
|
704
|
-
}), /* @__PURE__ */ jsx("input", {
|
|
705
|
-
type: "text",
|
|
706
|
-
spellCheck: false,
|
|
707
|
-
autoComplete: "off",
|
|
708
|
-
disabled: readOnly,
|
|
709
|
-
"aria-label": `${name} hex`,
|
|
710
|
-
value: hexDraft,
|
|
711
|
-
onChange: (event) => {
|
|
712
|
-
const next = event.target.value.trim();
|
|
713
|
-
setHexDraft(next);
|
|
714
|
-
if (isThemeHex(next)) commitHex(next);
|
|
838
|
+
event.stopPropagation();
|
|
839
|
+
toggleStep(step);
|
|
715
840
|
},
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
841
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
842
|
+
className: "bl-scale-card__chip-wrap",
|
|
843
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
844
|
+
className: "bl-scale-card__chip",
|
|
845
|
+
style: { backgroundColor: hslCss(state.scale[step]) }
|
|
846
|
+
}), /* @__PURE__ */ jsx(IncludeMark, { on })]
|
|
847
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
848
|
+
className: "bl-scale-card__step-label",
|
|
849
|
+
children: step
|
|
850
|
+
})]
|
|
851
|
+
}, step);
|
|
852
|
+
})
|
|
853
|
+
}),
|
|
854
|
+
/* @__PURE__ */ jsxs("div", {
|
|
855
|
+
className: "bl-scale-card__editors",
|
|
856
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", { children: "Available to page editors" }), /* @__PURE__ */ jsxs("p", { children: [
|
|
857
|
+
included.size,
|
|
858
|
+
" of ",
|
|
859
|
+
SHADE_STEPS.length,
|
|
860
|
+
" shades available · Choose which shades editors can select when building pages."
|
|
861
|
+
] })] }), /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("button", {
|
|
862
|
+
type: "button",
|
|
724
863
|
disabled: readOnly,
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
value: step,
|
|
729
|
-
children: step
|
|
730
|
-
}, step))
|
|
731
|
-
})]
|
|
732
|
-
})]
|
|
733
|
-
}),
|
|
734
|
-
role ? /* @__PURE__ */ jsxs("div", {
|
|
735
|
-
className: "bl-scale-card__family",
|
|
736
|
-
"data-role": role,
|
|
737
|
-
"data-drift": hueDrift ? "" : void 0,
|
|
738
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
739
|
-
className: "bl-scale-card__family-mark",
|
|
740
|
-
"aria-hidden": "true",
|
|
741
|
-
children: "!"
|
|
742
|
-
}), /* @__PURE__ */ jsxs("div", { children: [
|
|
743
|
-
/* @__PURE__ */ jsx("div", {
|
|
744
|
-
className: "bl-scale-card__family-title",
|
|
745
|
-
children: STATUS_COPY[role].title
|
|
746
|
-
}),
|
|
747
|
-
/* @__PURE__ */ jsx("p", { children: STATUS_COPY[role].body }),
|
|
748
|
-
hueDrift ? /* @__PURE__ */ jsx("p", {
|
|
749
|
-
className: "bl-scale-card__family-drift",
|
|
750
|
-
children: STATUS_COPY[role].drift
|
|
751
|
-
}) : null
|
|
752
|
-
] })]
|
|
753
|
-
}) : null,
|
|
754
|
-
/* @__PURE__ */ jsxs("div", {
|
|
755
|
-
className: "bl-scale-card__scale-head",
|
|
756
|
-
children: [/* @__PURE__ */ jsx("span", { children: "Generated scale" }), /* @__PURE__ */ jsxs("span", { children: [SHADE_STEPS.length, " shades"] })]
|
|
757
|
-
}),
|
|
758
|
-
/* @__PURE__ */ jsx("div", {
|
|
759
|
-
className: "bl-scale-card__steps",
|
|
760
|
-
role: "group",
|
|
761
|
-
"aria-label": `${name} scale steps`,
|
|
762
|
-
children: SHADE_STEPS.map((step) => {
|
|
763
|
-
const source = step === state.sourceStep;
|
|
764
|
-
const on = included.has(step);
|
|
765
|
-
return /* @__PURE__ */ jsxs("button", {
|
|
864
|
+
onClick: () => onChange(setColorScaleInclude(state, "all")),
|
|
865
|
+
children: "Include all"
|
|
866
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
766
867
|
type: "button",
|
|
767
|
-
className: "bl-scale-card__step",
|
|
768
|
-
"data-source": source ? "" : void 0,
|
|
769
|
-
"data-excluded": on ? void 0 : "",
|
|
770
|
-
"data-shake": shakeStep === step ? "" : void 0,
|
|
771
868
|
disabled: readOnly,
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
type: "button",
|
|
802
|
-
disabled: readOnly,
|
|
803
|
-
onClick: () => onChange(setColorScaleInclude(state, "all")),
|
|
804
|
-
children: "Include all"
|
|
805
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
806
|
-
type: "button",
|
|
807
|
-
disabled: readOnly,
|
|
808
|
-
onClick: () => onChange(setColorScaleInclude(state, "source")),
|
|
809
|
-
children: "Source only"
|
|
810
|
-
})] })]
|
|
811
|
-
}),
|
|
812
|
-
attentionOpen && warning ? /* @__PURE__ */ jsx(ThemePortal, { children: /* @__PURE__ */ jsx("div", {
|
|
813
|
-
className: "bl-scale-card__modal",
|
|
814
|
-
role: "dialog",
|
|
815
|
-
"aria-modal": "true",
|
|
816
|
-
"aria-labelledby": titleId,
|
|
817
|
-
onClick: (event) => {
|
|
818
|
-
if (event.target === event.currentTarget) setAttentionOpen(false);
|
|
819
|
-
},
|
|
820
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
821
|
-
className: "bl-scale-card__panel",
|
|
822
|
-
children: [
|
|
823
|
-
/* @__PURE__ */ jsxs("div", {
|
|
824
|
-
className: "bl-scale-card__panel-head",
|
|
825
|
-
children: [/* @__PURE__ */ jsx("h4", {
|
|
826
|
-
id: titleId,
|
|
827
|
-
children: readabilityHeadline(warning)
|
|
828
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
869
|
+
onClick: () => onChange(setColorScaleInclude(state, "source")),
|
|
870
|
+
children: "Source only"
|
|
871
|
+
})] })]
|
|
872
|
+
}),
|
|
873
|
+
attentionOpen && warning ? /* @__PURE__ */ jsx(ThemePortal, { children: /* @__PURE__ */ jsx("div", {
|
|
874
|
+
className: "bl-scale-card__modal",
|
|
875
|
+
role: "dialog",
|
|
876
|
+
"aria-modal": "true",
|
|
877
|
+
"aria-labelledby": titleId,
|
|
878
|
+
onClick: (event) => {
|
|
879
|
+
if (event.target === event.currentTarget) setAttentionOpen(false);
|
|
880
|
+
},
|
|
881
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
882
|
+
className: "bl-scale-card__panel",
|
|
883
|
+
children: [
|
|
884
|
+
/* @__PURE__ */ jsxs("div", {
|
|
885
|
+
className: "bl-scale-card__panel-head",
|
|
886
|
+
children: [/* @__PURE__ */ jsx("h4", {
|
|
887
|
+
id: titleId,
|
|
888
|
+
children: readabilityHeadline(warning)
|
|
889
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
890
|
+
type: "button",
|
|
891
|
+
onClick: () => setAttentionOpen(false),
|
|
892
|
+
"aria-label": "Close",
|
|
893
|
+
children: "×"
|
|
894
|
+
})]
|
|
895
|
+
}),
|
|
896
|
+
/* @__PURE__ */ jsx(ReadabilityDetail, { item: warning }),
|
|
897
|
+
/* @__PURE__ */ jsx("button", {
|
|
829
898
|
type: "button",
|
|
899
|
+
className: "bl-scale-card__panel-done",
|
|
830
900
|
onClick: () => setAttentionOpen(false),
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
className: "bl-scale-card__panel-done",
|
|
839
|
-
onClick: () => setAttentionOpen(false),
|
|
840
|
-
children: "Keep editing this color"
|
|
841
|
-
})
|
|
842
|
-
]
|
|
843
|
-
})
|
|
844
|
-
}) }) : null
|
|
845
|
-
]
|
|
901
|
+
children: "Keep editing this color"
|
|
902
|
+
})
|
|
903
|
+
]
|
|
904
|
+
})
|
|
905
|
+
}) }) : null
|
|
906
|
+
]
|
|
907
|
+
})
|
|
846
908
|
});
|
|
847
909
|
}
|
|
848
910
|
const COLOR_SCALE_CARD_CSS = `
|
|
@@ -850,18 +912,10 @@ const COLOR_SCALE_CARD_CSS = `
|
|
|
850
912
|
.bl-scale-card__head{display:flex;justify-content:space-between;gap:1rem;align-items:flex-start}
|
|
851
913
|
.bl-scale-card__title-row{position:relative;display:flex;align-items:center;flex-wrap:wrap;gap:.5rem}
|
|
852
914
|
.bl-scale-card__title{margin:0;font-size:1rem}
|
|
853
|
-
.bl-scale-card__badge{font:inherit;font-size:10px;text-transform:uppercase;letter-spacing:.04em;padding:.15rem .45rem;border-radius:999px;border:0;background:#e2e8f0;color:#0f172a}
|
|
854
|
-
.bl-scale-card__badge--attention{background:#fff1f2;color:#be123c;cursor:pointer}
|
|
855
915
|
.bl-scale-card__hint{margin:.35rem 0 0;color:var(--bl-preview-muted,var(--theme-elevation-500,#64748b));font-size:12px}
|
|
856
916
|
.bl-scale-card__delete{border:0;background:none;color:#be123c;font:inherit;font-size:13px;font-weight:600;cursor:pointer}
|
|
857
|
-
.bl-scale-card__row{display:grid;grid-template-columns:1fr 8rem;gap:.75rem;margin-top:1rem}
|
|
858
|
-
.bl-scale-
|
|
859
|
-
.bl-scale-card__hex-wrap{display:flex;border:1px solid var(--bl-preview-border,var(--theme-elevation-150,#e2e8f0));border-radius:8px;background:var(--bl-preview-card,var(--theme-input-bg,#fff))}
|
|
860
|
-
.bl-scale-card__hex-wrap input[type=color]{width:2.75rem;height:2.25rem;padding:0;border:0;border-right:1px solid var(--bl-preview-border,var(--theme-elevation-150,#e2e8f0));border-radius:8px 0 0 8px;background:transparent;cursor:pointer;color-scheme:light;appearance:none;-webkit-appearance:none}
|
|
861
|
-
.bl-scale-card__hex-wrap input[type=color]::-webkit-color-swatch-wrapper{padding:0}
|
|
862
|
-
.bl-scale-card__hex-wrap input[type=color]::-webkit-color-swatch{border:0;border-radius:0;width:100%;height:100%}
|
|
863
|
-
.bl-scale-card__hex-wrap input[type=text]{flex:1;min-width:0;border:0;padding:.4rem .7rem;font-family:var(--font-mono,ui-monospace,monospace);font-size:13px;background:transparent;color:inherit;border-radius:0 8px 8px 0}
|
|
864
|
-
.bl-scale-card__field select{min-height:2.25rem;border:1px solid var(--bl-preview-border,var(--theme-elevation-150,#e2e8f0));border-radius:8px;padding:.35rem .5rem;background:var(--bl-preview-card,var(--theme-input-bg,#fff));color:inherit}
|
|
917
|
+
.bl-scale-card__row{display:grid;grid-template-columns:1fr 8rem;gap:.75rem;margin-top:1rem;align-items:start}
|
|
918
|
+
.bl-scale-card__row .bl-nav-kit__field{margin-bottom:0}
|
|
865
919
|
.bl-scale-card__family{display:flex;gap:.75rem;align-items:flex-start;margin-top:1rem;padding:.75rem .85rem;border-radius:8px}
|
|
866
920
|
.bl-scale-card__family[data-role=success]{border:1px solid #a7f3d0;background:#ecfdf5;color:#065f46}
|
|
867
921
|
.bl-scale-card__family[data-role=destructive]{border:1px solid #fecdd3;background:#fff1f2;color:#9f1239}
|
|
@@ -1122,63 +1176,52 @@ const LibraryField = ({ field, path, readOnly }) => {
|
|
|
1122
1176
|
})]
|
|
1123
1177
|
}),
|
|
1124
1178
|
adding ? /* @__PURE__ */ jsx(ThemePortal, { children: /* @__PURE__ */ jsx("div", {
|
|
1125
|
-
className: "bl-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1179
|
+
className: "bl-theme-dialog",
|
|
1180
|
+
children: /* @__PURE__ */ jsx(KitProvider, { children: /* @__PURE__ */ jsxs(Dialog, {
|
|
1181
|
+
open: true,
|
|
1182
|
+
title: "New color",
|
|
1183
|
+
onCancel: () => {
|
|
1184
|
+
setAdding(false);
|
|
1185
|
+
setName("");
|
|
1186
|
+
setHex("");
|
|
1187
|
+
setSourceStep(500);
|
|
1188
|
+
},
|
|
1189
|
+
confirmLabel: "Create color scale",
|
|
1190
|
+
onConfirm: add,
|
|
1191
|
+
confirmDisabled: !slugify(name) || !isThemeHex(hex),
|
|
1134
1192
|
children: [
|
|
1135
|
-
/* @__PURE__ */
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
id: "bl-library-add-title",
|
|
1139
|
-
children: "New color"
|
|
1140
|
-
}), /* @__PURE__ */ jsx("p", { children: "Give it a useful name, enter your brand hex, then say which scale step that hex is." })] }), /* @__PURE__ */ jsx("button", {
|
|
1141
|
-
type: "button",
|
|
1142
|
-
onClick: () => setAdding(false),
|
|
1143
|
-
"aria-label": "Close",
|
|
1144
|
-
children: "×"
|
|
1145
|
-
})]
|
|
1146
|
-
}),
|
|
1147
|
-
/* @__PURE__ */ jsxs("label", { children: ["Name", /* @__PURE__ */ jsx("input", {
|
|
1193
|
+
/* @__PURE__ */ jsx("p", { children: "Give it a useful name, enter your brand hex, then say which scale step that hex is." }),
|
|
1194
|
+
/* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(Label, { children: "Name" }), /* @__PURE__ */ jsx(Input, {
|
|
1195
|
+
"aria-label": "Name",
|
|
1148
1196
|
value: name,
|
|
1149
1197
|
placeholder: "e.g. Coral",
|
|
1150
1198
|
onChange: (event) => setName(event.target.value)
|
|
1151
1199
|
})] }),
|
|
1152
|
-
/* @__PURE__ */ jsxs(
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
1174
|
-
type: "button",
|
|
1175
|
-
disabled: !slugify(name) || !isThemeHex(hex),
|
|
1176
|
-
onClick: add,
|
|
1177
|
-
children: "Create color scale"
|
|
1200
|
+
/* @__PURE__ */ jsxs(Field, {
|
|
1201
|
+
as: "div",
|
|
1202
|
+
children: [/* @__PURE__ */ jsx(Label, { children: "Brand hex" }), /* @__PURE__ */ jsx(BrandHexField, {
|
|
1203
|
+
name: "Brand",
|
|
1204
|
+
value: hex,
|
|
1205
|
+
onChange: setHex,
|
|
1206
|
+
picker: "inline"
|
|
1207
|
+
})]
|
|
1208
|
+
}),
|
|
1209
|
+
/* @__PURE__ */ jsxs(Field, {
|
|
1210
|
+
as: "div",
|
|
1211
|
+
children: [/* @__PURE__ */ jsx(Label, { children: "This color is" }), /* @__PURE__ */ jsxs(Select, {
|
|
1212
|
+
value: String(sourceStep),
|
|
1213
|
+
onValueChange: (value) => setSourceStep(Number(value)),
|
|
1214
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
1215
|
+
"aria-label": "This color is",
|
|
1216
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
1217
|
+
}), /* @__PURE__ */ jsx(SelectContent, { children: SHADE_STEPS.map((step) => /* @__PURE__ */ jsx(SelectItem, {
|
|
1218
|
+
value: String(step),
|
|
1219
|
+
children: step
|
|
1220
|
+
}, step)) })]
|
|
1178
1221
|
})]
|
|
1179
1222
|
})
|
|
1180
1223
|
]
|
|
1181
|
-
})
|
|
1224
|
+
}) })
|
|
1182
1225
|
}) }) : null,
|
|
1183
1226
|
replacing ? /* @__PURE__ */ jsx(ThemePortal, { children: /* @__PURE__ */ jsx("div", {
|
|
1184
1227
|
className: "bl-library__modal",
|
|
@@ -1278,26 +1321,24 @@ const CSS$3 = `
|
|
|
1278
1321
|
.bl-library__panel-head button{border:0;background:none;font:inherit;font-size:1.25rem;line-height:1;color:#94a3b8;cursor:pointer}
|
|
1279
1322
|
.bl-library__panel h2{margin:0}
|
|
1280
1323
|
.bl-library__panel p{margin:.5rem 0 0;color:#475569;font-size:14px}
|
|
1281
|
-
.bl-library__panel label{display:flex;flex-direction:column;gap:.4rem;margin-top:1rem;font-size:13px;font-weight:600}
|
|
1324
|
+
.bl-library__panel label,.bl-library__field{display:flex;flex-direction:column;gap:.4rem;margin-top:1rem;font-size:13px;font-weight:600}
|
|
1282
1325
|
.bl-library__panel input,.bl-library__panel select{min-height:2.25rem;border:1px solid #cbd5e1;border-radius:8px;padding:.35rem .5rem;background:#fff;color:#0f172a}
|
|
1283
1326
|
.bl-library__usages{margin:1rem 0 0;padding-left:1.1rem;color:#475569;font-size:13px;font-weight:400}
|
|
1284
1327
|
.bl-library__usages li{margin:.25rem 0}
|
|
1285
1328
|
.bl-library__actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:.5rem;margin-top:1rem}
|
|
1286
1329
|
.bl-library__actions button:last-child{border:0;background:#0f172a;color:#fff;font-weight:600}
|
|
1287
1330
|
.bl-library__actions button:last-child:disabled{opacity:.4;cursor:not-allowed}
|
|
1331
|
+
.bl-theme-dialog .bl-nav-kit__modal{z-index:10000}
|
|
1288
1332
|
`;
|
|
1289
1333
|
//#endregion
|
|
1290
1334
|
//#region src/admin/typography-pairing.tsx
|
|
1291
1335
|
function FontRoleCard({ title, hint, required, family, preview, children }) {
|
|
1292
|
-
return /* @__PURE__ */ jsxs("article", {
|
|
1336
|
+
return /* @__PURE__ */ jsx(KitProvider, { children: /* @__PURE__ */ jsxs("article", {
|
|
1293
1337
|
className: "bl-font-role",
|
|
1294
1338
|
children: [
|
|
1295
1339
|
/* @__PURE__ */ jsxs("header", {
|
|
1296
1340
|
className: "bl-font-role__head",
|
|
1297
|
-
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", { children: title }), /* @__PURE__ */ jsx("p", { children: hint })] }), required ? /* @__PURE__ */ jsx("
|
|
1298
|
-
className: "bl-font-role__badge",
|
|
1299
|
-
children: "Required"
|
|
1300
|
-
}) : null]
|
|
1341
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", { children: title }), /* @__PURE__ */ jsx("p", { children: hint })] }), required ? /* @__PURE__ */ jsx(Badge, { children: "Required" }) : null]
|
|
1301
1342
|
}),
|
|
1302
1343
|
children,
|
|
1303
1344
|
/* @__PURE__ */ jsxs("div", {
|
|
@@ -1313,7 +1354,7 @@ function FontRoleCard({ title, hint, required, family, preview, children }) {
|
|
|
1313
1354
|
})]
|
|
1314
1355
|
})
|
|
1315
1356
|
]
|
|
1316
|
-
});
|
|
1357
|
+
}) });
|
|
1317
1358
|
}
|
|
1318
1359
|
function TypographyPairing({ headingFamily, bodyFamily }) {
|
|
1319
1360
|
return /* @__PURE__ */ jsxs("section", {
|
|
@@ -1358,7 +1399,6 @@ const TYPOGRAPHY_PAIRING_CSS = `
|
|
|
1358
1399
|
.bl-font-role__head{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem}
|
|
1359
1400
|
.bl-font-role__head h3{margin:0;font-size:1rem}
|
|
1360
1401
|
.bl-font-role__head p{margin:.3rem 0 0;font-size:12px;color:var(--bl-preview-muted,var(--theme-elevation-500,#64748b))}
|
|
1361
|
-
.bl-font-role__badge{font-size:10px;text-transform:uppercase;letter-spacing:.04em;padding:.15rem .45rem;border-radius:999px;background:#e2e8f0;color:#0f172a}
|
|
1362
1402
|
.bl-font-role__preview{margin-top:1rem;padding:.85rem .9rem;border:1px solid var(--bl-preview-border,var(--theme-elevation-150,#e2e8f0));border-radius:12px;background:var(--bl-preview-bg,var(--theme-elevation-50,#f8fafc))}
|
|
1363
1403
|
.bl-font-role__preview > span{display:block;margin-bottom:.4rem;font-size:11px;color:var(--bl-preview-muted,var(--theme-elevation-500,#64748b))}
|
|
1364
1404
|
.bl-font-role__heading{margin:0;font-size:1.5rem;line-height:1.2;font-weight:600}
|
|
@@ -1889,7 +1929,7 @@ const SWATCHES = [
|
|
|
1889
1929
|
];
|
|
1890
1930
|
function GreyScaleChoices({ value, onChange, readOnly }) {
|
|
1891
1931
|
const canvas = usePreviewCanvas();
|
|
1892
|
-
return /* @__PURE__ */ jsxs("section", {
|
|
1932
|
+
return /* @__PURE__ */ jsx(KitProvider, { children: /* @__PURE__ */ jsxs("section", {
|
|
1893
1933
|
className: `bl-grey ${canvas.className}`,
|
|
1894
1934
|
"data-preview": canvas.mode,
|
|
1895
1935
|
style: canvas.style,
|
|
@@ -1900,10 +1940,7 @@ function GreyScaleChoices({ value, onChange, readOnly }) {
|
|
|
1900
1940
|
}),
|
|
1901
1941
|
/* @__PURE__ */ jsxs("header", {
|
|
1902
1942
|
className: "bl-grey__head",
|
|
1903
|
-
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h2", { children: "Gray family" }), /* @__PURE__ */ jsx("p", { children: "Choose the neutral family used for page backgrounds, cards, borders, inputs, and muted text. Readability for these system neutrals is handled automatically." })] }), /* @__PURE__ */ jsx("
|
|
1904
|
-
className: "bl-grey__badge",
|
|
1905
|
-
children: "Required"
|
|
1906
|
-
})]
|
|
1943
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h2", { children: "Gray family" }), /* @__PURE__ */ jsx("p", { children: "Choose the neutral family used for page backgrounds, cards, borders, inputs, and muted text. Readability for these system neutrals is handled automatically." })] }), /* @__PURE__ */ jsx(Badge, { children: "Required" })]
|
|
1907
1944
|
}),
|
|
1908
1945
|
/* @__PURE__ */ jsx("div", {
|
|
1909
1946
|
className: "bl-grey__choices",
|
|
@@ -1937,7 +1974,7 @@ function GreyScaleChoices({ value, onChange, readOnly }) {
|
|
|
1937
1974
|
})
|
|
1938
1975
|
})
|
|
1939
1976
|
]
|
|
1940
|
-
});
|
|
1977
|
+
}) });
|
|
1941
1978
|
}
|
|
1942
1979
|
/**
|
|
1943
1980
|
* Visual picker over the five grey-scale presets. Replaces the stock select
|
|
@@ -1966,7 +2003,6 @@ const GREY_SCALE_FIELD_CSS = `
|
|
|
1966
2003
|
.bl-grey__head{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;margin:0;padding:1.1rem 1.15rem .85rem;border:1px solid var(--bl-preview-border,var(--theme-elevation-150,#e2e8f0));border-bottom:0;border-radius:12px 12px 0 0;background:var(--bl-preview-card,var(--theme-elevation-0,#fff));color:var(--bl-preview-text,inherit)}
|
|
1967
2004
|
.bl-grey__head h2{margin:0;font-size:1.1rem}
|
|
1968
2005
|
.bl-grey__head p{margin:.35rem 0 0;max-width:40rem;font-size:13px;color:var(--bl-preview-muted,var(--theme-elevation-500,#64748b))}
|
|
1969
|
-
.bl-grey__badge{font:inherit;font-size:10px;text-transform:uppercase;letter-spacing:.04em;padding:.15rem .45rem;border-radius:999px;background:#e2e8f0;color:#0f172a}
|
|
1970
2006
|
.bl-grey__choices{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:.6rem;padding:0 1.15rem 1.15rem;border:1px solid var(--bl-preview-border,var(--theme-elevation-150,#e2e8f0));border-top:0;border-radius:0 0 12px 12px;background:var(--bl-preview-card,var(--theme-elevation-0,#fff));color:var(--bl-preview-text,inherit)}
|
|
1971
2007
|
.bl-grey__choice{display:flex;flex-direction:column;gap:.45rem;padding:.75rem;border:1px solid var(--bl-preview-border,var(--theme-elevation-150,#e2e8f0));border-radius:12px;background:var(--bl-preview-bg,var(--theme-elevation-0,#fff));color:inherit;cursor:pointer}
|
|
1972
2008
|
.bl-grey__choice[data-selected]{box-shadow:inset 0 0 0 2px var(--bl-preview-text,#0f172a);border-color:var(--bl-preview-text,#0f172a)}
|
|
@@ -2325,9 +2361,8 @@ function ThemePublishActions({ child }) {
|
|
|
2325
2361
|
/* @__PURE__ */ jsx("style", {
|
|
2326
2362
|
href: "bl-publish-child",
|
|
2327
2363
|
precedence: "default",
|
|
2328
|
-
children:
|
|
2364
|
+
children: `.bl-publish-child{display:flex;align-items:center;justify-content:flex-end;gap:.5rem}.bl-publish-child__button{min-height:2.25rem;padding:.4rem 1rem;border:0;border-radius:8px;background:var(--theme-text,#0f172a);color:var(--theme-bg,#fff);font:inherit;font-weight:600;cursor:pointer}`
|
|
2329
2365
|
}),
|
|
2330
|
-
child !== "identity" ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ThemePreviewToggle, {}) }) : null,
|
|
2331
2366
|
/* @__PURE__ */ jsxs("button", {
|
|
2332
2367
|
type: "button",
|
|
2333
2368
|
className: "bl-publish-child__button",
|
|
@@ -2374,16 +2409,12 @@ function readActiveThemeTab(root = typeof document === "undefined" ? null : docu
|
|
|
2374
2409
|
//#endregion
|
|
2375
2410
|
//#region src/admin/save-button.tsx
|
|
2376
2411
|
/**
|
|
2377
|
-
* Light/Dark
|
|
2378
|
-
*
|
|
2379
|
-
* Save
|
|
2412
|
+
* Theme used to put a Light/Dark pair here. Admin chrome now follows
|
|
2413
|
+
* Payload's own theme from the header sun/moon, so this slot is empty
|
|
2414
|
+
* and Save stays in the Save slot.
|
|
2380
2415
|
*/
|
|
2381
2416
|
function ThemeDocumentControls() {
|
|
2382
|
-
return
|
|
2383
|
-
href: "bl-doc-controls",
|
|
2384
|
-
precedence: "default",
|
|
2385
|
-
children: THEME_PREVIEW_TOGGLE_CSS
|
|
2386
|
-
}), /* @__PURE__ */ jsx(ThemePreviewToggle, {})] });
|
|
2417
|
+
return null;
|
|
2387
2418
|
}
|
|
2388
2419
|
/**
|
|
2389
2420
|
* Import-map Save slot used by the older single-Global Theme. Theme pages
|
|
@@ -3316,6 +3347,44 @@ const FeaturesMatrixField = (props) => {
|
|
|
3316
3347
|
});
|
|
3317
3348
|
};
|
|
3318
3349
|
//#endregion
|
|
3350
|
+
//#region src/admin/theme-kit-accent.tsx
|
|
3351
|
+
function primaryHex(doc) {
|
|
3352
|
+
const hex = doc?.colors?.brand?.primary?.hex;
|
|
3353
|
+
return typeof hex === "string" && isThemeHex(hex) ? hex : void 0;
|
|
3354
|
+
}
|
|
3355
|
+
/**
|
|
3356
|
+
* Site Theme primary → `--bl-kit-accent`. Saved value for the whole
|
|
3357
|
+
* admin; the Primary color card also writes the live hex so pickers
|
|
3358
|
+
* and kit chrome update as the field is edited.
|
|
3359
|
+
*/
|
|
3360
|
+
function ThemeKitAccent({ children }) {
|
|
3361
|
+
const { config } = useConfig();
|
|
3362
|
+
const [accent, setAccent] = useState();
|
|
3363
|
+
useEffect(() => {
|
|
3364
|
+
const url = `${config.serverURL}${config.routes.api}/globals/theme?depth=0`;
|
|
3365
|
+
let cancelled = false;
|
|
3366
|
+
function load() {
|
|
3367
|
+
fetch(url, { credentials: "include" }).then((response) => response.ok ? response.json() : null).then((doc) => {
|
|
3368
|
+
const hex = primaryHex(doc);
|
|
3369
|
+
if (!cancelled && hex) setAccent(hex);
|
|
3370
|
+
}).catch(() => void 0);
|
|
3371
|
+
}
|
|
3372
|
+
load();
|
|
3373
|
+
const onVis = () => {
|
|
3374
|
+
if (document.visibilityState === "visible") load();
|
|
3375
|
+
};
|
|
3376
|
+
document.addEventListener("visibilitychange", onVis);
|
|
3377
|
+
return () => {
|
|
3378
|
+
cancelled = true;
|
|
3379
|
+
document.removeEventListener("visibilitychange", onVis);
|
|
3380
|
+
};
|
|
3381
|
+
}, [config.serverURL, config.routes.api]);
|
|
3382
|
+
return /* @__PURE__ */ jsx(KitProvider, {
|
|
3383
|
+
accent,
|
|
3384
|
+
children
|
|
3385
|
+
});
|
|
3386
|
+
}
|
|
3387
|
+
//#endregion
|
|
3319
3388
|
//#region src/admin/document-title-actions.tsx
|
|
3320
3389
|
/**
|
|
3321
3390
|
* Shared document header: title on the left, primary actions on the
|
|
@@ -3357,7 +3426,7 @@ function DocumentTitleActions({ children }) {
|
|
|
3357
3426
|
});
|
|
3358
3427
|
return () => observer.disconnect();
|
|
3359
3428
|
}, []);
|
|
3360
|
-
return /* @__PURE__ */ jsxs(
|
|
3429
|
+
return /* @__PURE__ */ jsxs(ThemeKitAccent, { children: [/* @__PURE__ */ jsx("style", {
|
|
3361
3430
|
href: "bl-doc-title-actions",
|
|
3362
3431
|
precedence: "default",
|
|
3363
3432
|
children: TITLE_ACTIONS_CSS
|
|
@@ -3497,6 +3566,8 @@ function resolveAdminNav({ config, doc, visibleEntities }) {
|
|
|
3497
3566
|
//#endregion
|
|
3498
3567
|
//#region src/admin/admin-nav.tsx
|
|
3499
3568
|
const BASE = "nav";
|
|
3569
|
+
/** Survives AdminNav remounting on every admin route so the first-seen walk does not flash. */
|
|
3570
|
+
let cachedDoc;
|
|
3500
3571
|
function isAbortError(error) {
|
|
3501
3572
|
return error instanceof DOMException ? error.name === "AbortError" : error instanceof Error && error.name === "AbortError";
|
|
3502
3573
|
}
|
|
@@ -3529,7 +3600,7 @@ function AdminNavShell({ children }) {
|
|
|
3529
3600
|
*/
|
|
3530
3601
|
function AdminNav({ visibleEntities }) {
|
|
3531
3602
|
const { config } = useConfig();
|
|
3532
|
-
const [doc, setDoc] = useState(null);
|
|
3603
|
+
const [doc, setDoc] = useState(() => cachedDoc ?? null);
|
|
3533
3604
|
const adminRoute = config.routes.admin ?? "/admin";
|
|
3534
3605
|
const apiRoute = config.routes.api ?? "/api";
|
|
3535
3606
|
useEffect(() => {
|
|
@@ -3540,9 +3611,12 @@ function AdminNav({ visibleEntities }) {
|
|
|
3540
3611
|
signal: controller.signal
|
|
3541
3612
|
}).then((response) => response.ok ? response.json() : null).then((payload) => {
|
|
3542
3613
|
if (controller.signal.aborted) return;
|
|
3614
|
+
cachedDoc = payload;
|
|
3543
3615
|
setDoc(payload);
|
|
3544
3616
|
}).catch((error) => {
|
|
3545
3617
|
if (isAbortError(error) || controller.signal.aborted) return;
|
|
3618
|
+
if (cachedDoc !== void 0) return;
|
|
3619
|
+
cachedDoc = null;
|
|
3546
3620
|
setDoc(null);
|
|
3547
3621
|
});
|
|
3548
3622
|
return () => controller.abort();
|
|
@@ -3669,6 +3743,6 @@ const AdminNavEntityField = ({ field, path, permissions, readOnly, schemaPath })
|
|
|
3669
3743
|
});
|
|
3670
3744
|
};
|
|
3671
3745
|
//#endregion
|
|
3672
|
-
export { AdminNav, AdminNavEntityField, AdminNavItemRowLabel, AdminNavRowLabel, AppearanceField, ColorField, ColorScaleField, ContrastReport, DocumentCreateNew, DocumentTitleActions, FeaturesMatrixField, FontField, GreyScaleField, HiddenSaveButton, IdentityFallback, LibraryField, LookField, PairingField, PublishChild, RoleNameField, RoleSlugField, RolesField, RolesGrantsField, RolesMatrixField, RolesRowLabel, SectionHeading, ThemeDocumentControls, ThemeSaveButton };
|
|
3746
|
+
export { AdminNav, AdminNavEntityField, AdminNavItemRowLabel, AdminNavRowLabel, AppearanceField, ColorField, ColorScaleField, ContrastReport, DocumentCreateNew, DocumentTitleActions, FeaturesMatrixField, FontField, GreyScaleField, HiddenSaveButton, IdentityFallback, LibraryField, LookField, PairingField, PublishChild, RoleNameField, RoleSlugField, RolesField, RolesGrantsField, RolesMatrixField, RolesRowLabel, SectionHeading, ThemeDocumentControls, ThemeSaveButton, setThemePreviewMode };
|
|
3673
3747
|
|
|
3674
3748
|
//# sourceMappingURL=admin.mjs.map
|