PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
24.1.0 24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 All 404 releases
← All changes | build/scripts/theme/index.js +373 -139 23.7.0 → trunk View file →
@@ -1,4 +1,6 @@
1 +(function() {
2 +"use strict";
1 3 var wp;
2 4 (wp ||= {}).theme = (() => {
3 5 var __create = Object.create;
4 6 var __defProp = Object.defineProperty;
@@ -3342,25 +3344,20 @@
3342 3344 }
3343 3345 }
3344 3346 });
3345 3347
3348 + // packages/theme/node_modules/colorjs.io/src/equals.js
3349 + function equals(color1, color2) {
3350 + color1 = getColor(color1);
3351 + color2 = getColor(color2);
3352 + return color1.space === color2.space && color1.alpha === color2.alpha && color1.coords.every((c, i) => c === color2.coords[i]);
3353 + }
3354 +
3346 3355 // packages/theme/node_modules/colorjs.io/src/luminance.js
3347 3356 function getLuminance(color) {
3348 3357 return get(color, [xyz_d65_default, "y"]);
3349 3358 }
3350 3359
3351 - // packages/theme/node_modules/colorjs.io/src/contrast/WCAG21.js
3352 - function contrastWCAG21(color1, color2) {
3353 - color1 = getColor(color1);
3354 - color2 = getColor(color2);
3355 - let Y1 = Math.max(getLuminance(color1), 0);
3356 - let Y2 = Math.max(getLuminance(color2), 0);
3357 - if (Y2 > Y1) {
3358 - [Y1, Y2] = [Y2, Y1];
3359 - }
3360 - return (Y1 + 0.05) / (Y2 + 0.05);
3361 - }
3362 -
3363 3360 // packages/theme/node_modules/colorjs.io/src/spaces/hsl.js
3364 3361 var hsl_default = new ColorSpace({
3365 3362 id: "hsl",
3366 3363 name: "HSL",
@@ -3522,13 +3519,13 @@
3522 3519 "background-interactive-neutral-weak",
3523 3520 "background-interactive-neutral-weak-disabled"
3524 3521 ],
3525 3522 "primary-bgFill1": ["background-interactive-brand-strong"],
3523 + "primary-bgFill2": ["background-interactive-brand-strong-active"],
3526 3524 "primary-fgFill": [
3527 3525 "foreground-interactive-brand-strong",
3528 3526 "foreground-interactive-brand-strong-active"
3529 3527 ],
3530 - "primary-bgFill2": ["background-interactive-brand-strong-active"],
3531 3528 "primary-surface4": ["background-interactive-brand-weak-active"],
3532 3529 "primary-fgSurface4": ["foreground-interactive-brand-active"],
3533 3530 "primary-fgSurface3": ["foreground-interactive-brand"],
3534 3531 "primary-stroke3": [
@@ -3559,13 +3556,13 @@
3559 3556 "warning-fgSurface3": ["foreground-content-warning-weak"],
3560 3557 "warning-stroke3": ["stroke-surface-warning-strong"],
3561 3558 "warning-stroke1": ["stroke-surface-warning"],
3562 3559 "error-bgFill1": ["background-interactive-error-strong"],
3560 + "error-bgFill2": ["background-interactive-error-strong-active"],
3563 3561 "error-fgFill": [
3564 3562 "foreground-interactive-error-strong",
3565 3563 "foreground-interactive-error-strong-active"
3566 3564 ],
3567 - "error-bgFill2": ["background-interactive-error-strong-active"],
3568 3565 "error-surface2": [
3569 3566 "background-interactive-error-active",
3570 3567 "background-surface-error-weak"
3571 3568 ],
@@ -3594,9 +3591,14 @@
3594 3591 "background-interactive-error-strong-disabled",
3595 3592 "background-interactive-neutral-strong-disabled"
3596 3593 ],
3597 3594 "bg-surface4": ["background-interactive-neutral-weak-active"],
3598 - "bg-surface3": ["background-surface-neutral-strong"],
3595 + "bg-surface3": [
3596 + "background-interactive-neutral",
3597 + "background-interactive-neutral-active",
3598 + "background-interactive-neutral-disabled",
3599 + "background-surface-neutral-strong"
3600 + ],
3599 3601 "bg-fgSurface4": [
3600 3602 "foreground-content-neutral",
3601 3603 "foreground-interactive-neutral",
3602 3604 "foreground-interactive-neutral-active",
@@ -3654,8 +3656,9 @@
3654 3656 };
3655 3657
3656 3658 // packages/theme/build-module/color-ramps/lib/color-utils.mjs
3657 3659 var ALLOWED_SEED_COLOR_SPACES = [srgb_default];
3660 + var objectLuminanceCache = /* @__PURE__ */ new WeakMap();
3658 3661 function getColorString(color) {
3659 3662 ColorSpace.register(srgb_default);
3660 3663 const rgbRounded = serialize(to(color, srgb_default));
3661 3664 return serialize(rgbRounded, { format: "hex" });
@@ -3660,12 +3663,33 @@
3660 3663 const rgbRounded = serialize(to(color, srgb_default));
3661 3664 return serialize(rgbRounded, { format: "hex" });
3662 3665 }
3663 3666 function getContrast(colorA, colorB) {
3664 - ColorSpace.register(srgb_default);
3665 - return contrastWCAG21(colorA, colorB);
3667 + return getContrastFromLuminances(
3668 + getRelativeLuminance(colorA),
3669 + getRelativeLuminance(colorB)
3670 + );
3666 3671 }
3667 - function assertValidSeedColor(seed) {
3672 + function getRelativeLuminance(color) {
3673 + if (typeof color === "string") {
3674 + ColorSpace.register(srgb_default);
3675 + return Math.max(getLuminance(color), 0);
3676 + }
3677 + const cachedLuminance = objectLuminanceCache.get(color);
3678 + if (cachedLuminance && equals(cachedLuminance.color, color)) {
3679 + return cachedLuminance.luminance;
3680 + }
3681 + const luminance = Math.max(getLuminance(color), 0);
3682 + objectLuminanceCache.set(color, {
3683 + color: clone(color),
3684 + luminance
3685 + });
3686 + return luminance;
3687 + }
3688 + function getContrastFromLuminances(first, second) {
3689 + return first > second ? (first + 0.05) / (second + 0.05) : (second + 0.05) / (first + 0.05);
3690 + }
3691 + function parseSeedColor(seed) {
3668 3692 ALLOWED_SEED_COLOR_SPACES.forEach(
3669 3693 (space) => ColorSpace.register(space)
3670 3694 );
3671 3695 let parsedColor;
@@ -3686,11 +3710,11 @@
3686 3710 throw new Error(
3687 3711 `Unsupported seed color "${seed}": expected a fully opaque color.`
3688 3712 );
3689 3713 }
3714 + return parsedColor;
3690 3715 }
3691 3716 function clampToGamut(c) {
3692 - ColorSpace.register(srgb_default);
3693 3717 return to(toGamut(c, { space: srgb_default, method: "css" }), oklch_default);
3694 3718 }
3695 3719
3696 3720 // packages/theme/build-module/color-ramps/lib/constants.mjs
@@ -3734,11 +3758,16 @@
3734 3758 dependents.set(step, []);
3735 3759 });
3736 3760 Object.entries(config).forEach(([stepName, stepConfig]) => {
3737 3761 const step = stepName;
3738 - const reference = stepConfig.contrast.reference;
3739 - dependencies.get(step).push(reference);
3740 - dependents.get(reference).push(step);
3762 + const references = [
3763 + stepConfig.contrast.reference,
3764 + ...stepConfig.contrast.additionalReferences ?? []
3765 + ];
3766 + for (const reference of references) {
3767 + dependencies.get(step).push(reference);
3768 + dependents.get(reference).push(step);
3769 + }
3741 3770 if (stepConfig.sameAsIfPossible) {
3742 3771 dependencies.get(step).push(stepConfig.sameAsIfPossible);
3743 3772 dependents.get(stepConfig.sameAsIfPossible).push(step);
3744 3773 }
@@ -3785,8 +3814,9 @@
3785 3814 if (!stepConfig) {
3786 3815 return;
3787 3816 }
3788 3817 visit(stepConfig.contrast.reference);
3818 + stepConfig.contrast.additionalReferences?.forEach(visit);
3789 3819 if (stepConfig.sameAsIfPossible) {
3790 3820 visit(stepConfig.sameAsIfPossible);
3791 3821 }
3792 3822 result.add(step);
@@ -3793,11 +3823,20 @@
3793 3823 }
3794 3824 visit(stepName);
3795 3825 return Array.from(result);
3796 3826 }
3797 - function computeBetterFgColorDirection(seed, preferLighter) {
3798 - const contrastAgainstBlack = getContrast(seed, BLACK);
3799 - const contrastAgainstWhite = getContrast(seed, WHITE);
3827 + function computeBetterFgColorDirection(references, preferLighter) {
3828 + const referenceColors = Array.isArray(references) ? references : [references];
3829 + const contrastAgainstBlack = Math.min(
3830 + ...referenceColors.map(
3831 + (reference) => getContrast(reference, BLACK)
3832 + )
3833 + );
3834 + const contrastAgainstWhite = Math.min(
3835 + ...referenceColors.map(
3836 + (reference) => getContrast(reference, WHITE)
3837 + )
3838 + );
3800 3839 return contrastAgainstBlack > contrastAgainstWhite + (preferLighter ? WHITE_TEXT_CONTRAST_MARGIN : 0) ? { better: "darker", worse: "lighter" } : { better: "lighter", worse: "darker" };
3801 3840 }
3802 3841 function adjustContrastTarget(target) {
3803 3842 if (target === 1) {
@@ -3848,13 +3887,12 @@
3848 3887 return bestC;
3849 3888 }
3850 3889
3851 3890 // packages/theme/build-module/color-ramps/lib/taper-chroma.mjs
3852 - function taperChroma(seed, lTarget, options = {}) {
3891 + function createChromaTaper(seed, options = {}) {
3853 3892 const gamut = options.gamut ?? srgb_default;
3854 3893 const alpha = options.alpha ?? 0.65;
3855 3894 const carry = options.carry ?? 0.5;
3856 - const cUpperBound = options.cUpperBound ?? 0.45;
3857 3895 const radiusLight = options.radiusLight ?? 0.2;
3858 3896 const radiusDark = options.radiusDark ?? 0.2;
3859 3897 const kLight = options.kLight ?? 0.85;
3860 3898 const kDark = options.kDark ?? 0.85;
@@ -3866,37 +3904,34 @@
3866 3904 if (chromaIsTiny || hueIsInvalid) {
3867 3905 if (typeof options.hueFallback === "number") {
3868 3906 hSeed = normalizeHue(options.hueFallback);
3869 3907 } else {
3870 - return {
3908 + return (lTarget) => ({
3871 3909 space: oklch_default,
3872 3910 coords: [clamp01(lTarget), 0, 0],
3873 3911 alpha: 1
3874 - };
3912 + });
3875 3913 }
3876 3914 }
3877 3915 const lSeed = clamp01(get(seed, [oklch_default, "l"]));
3878 - const cmaxSeed = getCachedMaxChromaAtLH(lSeed, hSeed, gamut, cUpperBound);
3879 - const cmaxTarget = getCachedMaxChromaAtLH(
3880 - clamp01(lTarget),
3881 - hSeed,
3882 - gamut,
3883 - cUpperBound
3884 - );
3885 - let seedRelative = 0;
3916 + const cmaxSeed = getMaxChromaAtLH(lSeed, hSeed, gamut);
3886 3917 const denom = cmaxSeed > 0 ? cmaxSeed : 1e-6;
3887 - seedRelative = clamp01(cSeed / denom);
3888 - const cIntendedBase = alpha * cmaxTarget;
3889 - const cWithCarry = cIntendedBase * Math.pow(seedRelative, clamp01(carry));
3890 - const t = continuousTaper(lSeed, lTarget, {
3891 - radiusLight,
3892 - radiusDark,
3893 - kLight,
3894 - kDark
3895 - });
3896 - const cPlanned = cWithCarry * t;
3897 - const lOut = clamp01(lTarget);
3898 - return { l: lOut, c: cPlanned };
3918 + const seedRelative = clamp01(cSeed / denom);
3919 + const seedCarry = Math.pow(seedRelative, clamp01(carry));
3920 + return (lTarget) => {
3921 + const cmaxTarget = getMaxChromaAtLH(clamp01(lTarget), hSeed, gamut);
3922 + const cIntendedBase = alpha * cmaxTarget;
3923 + const cWithCarry = cIntendedBase * seedCarry;
3924 + const t = continuousTaper(lSeed, lTarget, {
3925 + radiusLight,
3926 + radiusDark,
3927 + kLight,
3928 + kDark
3929 + });
3930 + const cPlanned = cWithCarry * t;
3931 + const lOut = clamp01(lTarget);
3932 + return { l: lOut, c: cPlanned };
3933 + };
3899 3934 }
3900 3935 function clamp01(x) {
3901 3936 if (x < 0) {
3902 3937 return 0;
@@ -3927,34 +3962,13 @@
3927 3962 const u = opts.radiusDark > 0 ? Math.abs(d2) / opts.radiusDark : 1;
3928 3963 const w = raisedCosine(u > 1 ? 1 : u);
3929 3964 return 1 - (1 - opts.kDark) * w;
3930 3965 }
3931 - var maxChromaCache = /* @__PURE__ */ new Map();
3932 - function keyMax(l, h, gamut, cap) {
3933 - const lq = quantize(l, 0.05);
3934 - const hq = quantize(normalizeHue(h), 10);
3935 - const cq = quantize(cap, 0.05);
3936 - return `${gamut}|L:${lq}|H:${hq}|cap:${cq}`;
3937 - }
3938 - function quantize(x, step) {
3939 - const k = Math.round(x / step);
3940 - return k * step;
3941 - }
3942 - function getCachedMaxChromaAtLH(l, h, gamutSpace, cap) {
3943 - const gamut = gamutSpace.id;
3944 - const key = keyMax(l, h, gamut, cap);
3945 - const hit = maxChromaCache.get(key);
3946 - if (typeof hit === "number") {
3947 - return hit;
3948 - }
3949 - const computed = maxInGamutChromaAtLH(l, h, gamutSpace, cap);
3950 - maxChromaCache.set(key, computed);
3951 - return computed;
3952 - }
3953 - function maxInGamutChromaAtLH(l, h, gamutSpace, cap) {
3966 + var MAX_CHROMA = 0.45;
3967 + function getMaxChromaAtLH(l, h, gamutSpace) {
3954 3968 const probe = {
3955 3969 space: oklch_default,
3956 - coords: [l, cap, h],
3970 + coords: [clamp01(l), MAX_CHROMA, normalizeHue(h)],
3957 3971 alpha: 1
3958 3972 };
3959 3973 const clamped = toGamutCSS(probe, { space: gamutSpace });
3960 3974 return get(clamped, [oklch_default, "c"]);
@@ -3974,13 +3988,16 @@
3974 3988 reached: true,
3975 3989 achieved: 1
3976 3990 };
3977 3991 }
3992 + const seedChroma = get(seed, [oklch_default, "c"]);
3993 + const seedHue = get(seed, [oklch_default, "h"]);
3994 + const taperChromaAtLightness = taperChromaOptions ? createChromaTaper(seed, taperChromaOptions) : void 0;
3978 3995 function getColorForL(l) {
3979 3996 let newL = l;
3980 - let newC = get(seed, [oklch_default, "c"]);
3981 - if (taperChromaOptions) {
3982 - const tapered = taperChroma(seed, newL, taperChromaOptions);
3997 + let newC = seedChroma;
3998 + if (taperChromaAtLightness) {
3999 + const tapered = taperChromaAtLightness(newL);
3983 4000 if ("l" in tapered && "c" in tapered) {
3984 4001 newL = tapered.l;
3985 4002 newC = tapered.c;
3986 4003 } else {
@@ -3988,9 +4005,9 @@
3988 4005 }
3989 4006 }
3990 4007 return clampToGamut({
3991 4008 space: oklch_default,
3992 - coords: [newL, newC, get(seed, [oklch_default, "h"])],
4009 + coords: [newL, newC, seedHue],
3993 4010 alpha: seed.alpha
3994 4011 });
3995 4012 }
3996 4013 const mostContrastingL = direction === "lighter" ? 1 : 0;
@@ -4054,9 +4071,9 @@
4054 4071 let maxDeficitStep;
4055 4072 const calculatedColors = /* @__PURE__ */ new Map();
4056 4073 calculatedColors.set("seed", seed);
4057 4074 for (const stepName of sortedSteps) {
4058 - let computeDirection = function(color, followDirection) {
4075 + let computeDirection2 = function(colors, followDirection) {
4059 4076 if (followDirection === "main") {
4060 4077 return mainDir;
4061 4078 }
4062 4079 if (followDirection === "opposite") {
@@ -4063,14 +4080,15 @@
4063 4080 return oppDir;
4064 4081 }
4065 4082 if (followDirection === "best") {
4066 4083 return computeBetterFgColorDirection(
4067 - color,
4084 + colors,
4068 4085 contrast.preferLighter
4069 4086 ).better;
4070 4087 }
4071 4088 return followDirection;
4072 4089 };
4090 + var computeDirection = computeDirection2;
4073 4091 const {
4074 4092 contrast,
4075 4093 lightness: stepLightnessConstraint,
4076 4094 taperChromaOptions,
@@ -4075,14 +4093,21 @@
4075 4093 lightness: stepLightnessConstraint,
4076 4094 taperChromaOptions,
4077 4095 sameAsIfPossible
4078 4096 } = config[stepName];
4079 - const referenceColor = calculatedColors.get(contrast.reference);
4080 - if (!referenceColor) {
4081 - throw new Error(
4082 - `Reference color for step ${stepName} not found: ${contrast.reference}`
4083 - );
4084 - }
4097 + const referenceNames = [
4098 + contrast.reference,
4099 + ...contrast.additionalReferences ?? []
4100 + ];
4101 + const referenceColors = referenceNames.map((referenceName) => {
4102 + const referenceColor2 = calculatedColors.get(referenceName);
4103 + if (!referenceColor2) {
4104 + throw new Error(
4105 + `Reference color for step ${stepName} not found: ${referenceName}`
4106 + );
4107 + }
4108 + return referenceColor2;
4109 + });
4085 4110 if (sameAsIfPossible) {
4086 4111 const candidateColor = calculatedColors.get(sameAsIfPossible);
4087 4112 if (!candidateColor) {
4088 4113 throw new Error(
@@ -4088,23 +4113,26 @@
4088 4113 throw new Error(
4089 4114 `Same-as color for step ${stepName} not found: ${sameAsIfPossible}`
4090 4115 );
4091 4116 }
4092 - const candidateContrast = getContrast(
4093 - referenceColor,
4094 - candidateColor
4117 + const adjustedTarget2 = adjustContrastTarget(contrast.target);
4118 + const candidateMeetsTarget = referenceColors.every(
4119 + (referenceColor2) => getContrast(referenceColor2, candidateColor) >= adjustedTarget2
4095 4120 );
4096 - const adjustedTarget2 = adjustContrastTarget(contrast.target);
4097 - if (candidateContrast >= adjustedTarget2) {
4121 + if (candidateMeetsTarget) {
4098 4122 calculatedColors.set(stepName, candidateColor);
4099 4123 rampResults[stepName] = getColorString(candidateColor);
4100 4124 continue;
4101 4125 }
4102 4126 }
4103 - const computedDir = computeDirection(
4104 - referenceColor,
4127 + const computedDir = computeDirection2(
4128 + referenceColors,
4105 4129 contrast.followDirection
4106 4130 );
4131 + const endpoint = computedDir === "lighter" ? WHITE : BLACK;
4132 + const referenceColor = referenceColors.reduce(
4133 + (tightest, current) => getContrast(current, endpoint) < getContrast(tightest, endpoint) ? current : tightest
4134 + );
4107 4135 const adjustedTarget = adjustContrastTarget(contrast.target);
4108 4136 let lightnessConstraint;
4109 4137 if (pinLightness?.stepName === stepName) {
4110 4138 lightnessConstraint = {
@@ -4151,12 +4179,12 @@
4151 4179 mainDirection,
4152 4180 pinLightness,
4153 4181 rescaleToFitContrastTargets = true
4154 4182 } = {}) {
4155 - assertValidSeedColor(seedArg);
4183 + const parsedSeed = parseSeedColor(seedArg);
4156 4184 let seed;
4157 4185 try {
4158 - seed = clampToGamut(seedArg);
4186 + seed = clampToGamut(parsedSeed);
4159 4187 } catch (error) {
4160 4188 throw new Error(
4161 4189 `Invalid seed color "${seedArg}": ${error instanceof Error ? error.message : "Unknown error"}`
4162 4190 );
@@ -4186,12 +4214,13 @@
4186 4214 oppDir,
4187 4215 pinLightness
4188 4216 });
4189 4217 let bestRamp = rampResults;
4218 + let bestWarnings = warnings;
4190 4219 if (maxDeficit > CONTRAST_EPSILON && rescaleToFitContrastTargets) {
4191 - let getSeedForL = function(l) {
4220 + let getSeedForL2 = function(l) {
4192 4221 return clampToGamut(set(clone(seed), [oklch_default, "l"], l));
4193 - }, getDeficitForSeed = function(s) {
4222 + }, getDeficitForSeed2 = function(s) {
4194 4223 const iterationResults = calculateRamp({
4195 4224 seed: s,
4196 4225 sortedSteps: iterSteps,
4197 4226 config,
@@ -4200,8 +4229,9 @@
4200 4229 pinLightness
4201 4230 });
4202 4231 return iterationResults.maxDeficitDirection === maxDeficitDirection ? iterationResults.maxDeficit : -maxDeficit;
4203 4232 };
4233 + var getSeedForL = getSeedForL2, getDeficitForSeed = getDeficitForSeed2;
4204 4234 const iterSteps = stepsForStep(maxDeficitStep, config);
4205 4235 const lowerSeedL = maxDeficitDirection === "lighter" ? 0 : 1;
4206 4236 const lowerDeficit = -maxDeficit;
4207 4237 const upperSeedL = get(seed, [oklch_default, "l"]);
@@ -4206,16 +4236,16 @@
4206 4236 const lowerDeficit = -maxDeficit;
4207 4237 const upperSeedL = get(seed, [oklch_default, "l"]);
4208 4238 const upperDeficit = maxDeficit;
4209 4239 const bestSeed = solveWithBisect(
4210 - getSeedForL,
4211 - getDeficitForSeed,
4240 + getSeedForL2,
4241 + getDeficitForSeed2,
4212 4242 lowerSeedL,
4213 4243 lowerDeficit,
4214 4244 upperSeedL,
4215 4245 upperDeficit
4216 4246 );
4217 - bestRamp = calculateRamp({
4247 + const finalResult = calculateRamp({
4218 4248 seed: bestSeed,
4219 4249 sortedSteps,
4220 4250 config,
4221 4251 mainDir,
@@ -4220,9 +4250,11 @@
4220 4250 config,
4221 4251 mainDir,
4222 4252 oppDir,
4223 4253 pinLightness
4224 - }).rampResults;
4254 + });
4255 + bestRamp = finalResult.rampResults;
4256 + bestWarnings = finalResult.warnings;
4225 4257 }
4226 4258 if (mainDir === "darker") {
4227 4259 const tmpSurface1 = bestRamp.surface1;
4228 4260 bestRamp.surface1 = bestRamp.surface3;
@@ -4229,9 +4261,9 @@
4229 4261 bestRamp.surface3 = tmpSurface1;
4230 4262 }
4231 4263 return {
4232 4264 ramp: bestRamp,
4233 - warnings,
4265 + warnings: bestWarnings,
4234 4266 direction: mainDir
4235 4267 };
4236 4268 }
4237 4269
@@ -4420,11 +4452,12 @@
4420 4452 // fgFill
4421 4453 fgFill: {
4422 4454 contrast: {
4423 4455 reference: "bgFill1",
4456 + additionalReferences: ["bgFill2"],
4424 4457 followDirection: "best",
4425 - target: 4.5,
4426 - preferLighter: true
4458 + // Preserve the 4.5:1 WCAG floor after 8-bit sRGB serialization.
4459 + target: 4.55
4427 4460 },
4428 4461 lightness: lightnessConstraintForegroundHighContrast,
4429 4462 taperChromaOptions: FG_TAPER_CHROMA
4430 4463 },
@@ -4549,8 +4582,160 @@
4549 4582 const bgRampInfo = bgRamp ? getBgRampInfo(bgRamp) : void 0;
4550 4583 return buildRamp(seed, ACCENT_RAMP_CONFIG, bgRampInfo);
4551 4584 }
4552 4585
4586 + // packages/theme/build-module/semantic-color-contrast-pairs.mjs
4587 + var MINIMUM_TEXT_CONTRAST = 4.5;
4588 + var SEMANTIC_COLOR_CONTRAST_PAIRS = [
4589 + {
4590 + background: "background.interactive.neutral",
4591 + foreground: "foreground.interactive.neutral"
4592 + },
4593 + {
4594 + background: "background.interactive.neutral",
4595 + foreground: "foreground.interactive.neutral-weak"
4596 + },
4597 + {
4598 + background: "background.interactive.neutral-active",
4599 + foreground: "foreground.interactive.neutral"
4600 + },
4601 + {
4602 + background: "background.interactive.neutral-active",
4603 + foreground: "foreground.interactive.neutral-weak"
4604 + },
4605 + {
4606 + background: "background.interactive.neutral-weak-active",
4607 + foreground: "foreground.interactive.neutral-active"
4608 + },
4609 + {
4610 + background: "background.surface.neutral",
4611 + foreground: "foreground.content.neutral"
4612 + },
4613 + {
4614 + background: "background.surface.neutral-strong",
4615 + foreground: "foreground.content.neutral"
4616 + },
4617 + {
4618 + background: "background.surface.neutral-weak",
4619 + foreground: "foreground.content.neutral"
4620 + },
4621 + {
4622 + background: "background.surface.neutral",
4623 + foreground: "foreground.content.neutral-weak"
4624 + },
4625 + {
4626 + background: "background.surface.info",
4627 + foreground: "foreground.content.info"
4628 + },
4629 + {
4630 + background: "background.surface.info-weak",
4631 + foreground: "foreground.content.info-weak"
4632 + },
4633 + {
4634 + background: "background.surface.success",
4635 + foreground: "foreground.content.success"
4636 + },
4637 + {
4638 + background: "background.surface.success-weak",
4639 + foreground: "foreground.content.success-weak"
4640 + },
4641 + {
4642 + background: "background.surface.warning",
4643 + foreground: "foreground.content.warning"
4644 + },
4645 + {
4646 + background: "background.surface.warning-weak",
4647 + foreground: "foreground.content.warning-weak"
4648 + },
4649 + {
4650 + background: "background.surface.caution",
4651 + foreground: "foreground.content.caution"
4652 + },
4653 + {
4654 + background: "background.surface.caution-weak",
4655 + foreground: "foreground.content.caution-weak"
4656 + },
4657 + {
4658 + background: "background.surface.error",
4659 + foreground: "foreground.content.error"
4660 + },
4661 + {
4662 + background: "background.surface.error-weak",
4663 + foreground: "foreground.content.error-weak"
4664 + },
4665 + {
4666 + background: "background.interactive.brand-strong",
4667 + foreground: "foreground.interactive.brand-strong"
4668 + },
4669 + {
4670 + background: "background.interactive.brand-strong-active",
4671 + foreground: "foreground.interactive.brand-strong-active"
4672 + },
4673 + {
4674 + background: "background.interactive.error-strong",
4675 + foreground: "foreground.interactive.error-strong"
4676 + },
4677 + {
4678 + background: "background.interactive.error-strong-active",
4679 + foreground: "foreground.interactive.error-strong-active"
4680 + },
4681 + {
4682 + background: "background.interactive.neutral-strong",
4683 + foreground: "foreground.interactive.neutral-strong"
4684 + },
4685 + {
4686 + background: "background.interactive.neutral-strong-active",
4687 + foreground: "foreground.interactive.neutral-strong-active"
4688 + }
4689 + ];
4690 + function getSemanticColorCustomProperty(token) {
4691 + return `--wpds-color-${token.replaceAll(".", "-")}`;
4692 + }
4693 +
4694 + // packages/theme/build-module/theme-provider-color-warnings.mjs
4695 + function collectThemeProviderColorWarnings(ramps, colorValues) {
4696 + const warnings = [];
4697 + for (const [rampName, result] of ramps) {
4698 + for (const step of result.warnings ?? []) {
4699 + warnings.push({
4700 + type: "ramp",
4701 + ramp: rampName,
4702 + step
4703 + });
4704 + }
4705 + }
4706 + for (const {
4707 + background: backgroundToken,
4708 + foreground: foregroundToken
4709 + } of SEMANTIC_COLOR_CONTRAST_PAIRS) {
4710 + const backgroundColor = colorValues.get(
4711 + getSemanticColorCustomProperty(backgroundToken)
4712 + );
4713 + const foregroundColor = colorValues.get(
4714 + getSemanticColorCustomProperty(foregroundToken)
4715 + );
4716 + if (backgroundColor === void 0 || foregroundColor === void 0) {
4717 + continue;
4718 + }
4719 + const achievedContrast = getContrast(
4720 + backgroundColor,
4721 + foregroundColor
4722 + );
4723 + if (achievedContrast < MINIMUM_TEXT_CONTRAST) {
4724 + warnings.push({
4725 + type: "contrast",
4726 + backgroundToken,
4727 + backgroundColor,
4728 + foregroundToken,
4729 + foregroundColor,
4730 + requiredContrast: MINIMUM_TEXT_CONTRAST,
4731 + achievedContrast
4732 + });
4733 + }
4734 + }
4735 + return warnings;
4736 + }
4737 +
4553 4738 // packages/theme/build-module/use-theme-provider-styles.mjs
4554 4739 var getCachedBgRamp = memize(buildBgRamp, { maxSize: 10 });
4555 4740 var getCachedAccentRamp = memize(buildAccentRamp, { maxSize: 10 });
4556 4741 var legacyWpComponentsOverridesCSS = [
@@ -4646,9 +4831,10 @@
4646 4831 function colorTokensCSS(computedColorRamps) {
4647 4832 const entries = [];
4648 4833 for (const [rampName, { ramp }] of computedColorRamps) {
4649 4834 for (const [tokenName, tokenValue] of Object.entries(ramp)) {
4650 - const key = `${rampName}-${tokenName}`;
4835 + const primitiveRampName = rampName === "background" ? "bg" : rampName;
4836 + const key = `${primitiveRampName}-${tokenName}`;
4651 4837 const aliasedBy = color_tokens_default[key] ?? [];
4652 4838 for (const aliasedId of aliasedBy) {
4653 4839 entries.push([`--wpds-color-${aliasedId}`, tokenValue]);
4654 4840 }
@@ -4657,14 +4843,14 @@
4657 4843 return entries;
4658 4844 }
4659 4845 function generateStyles({
4660 4846 primary,
4661 - computedColorRamps
4847 + colorEntries
4662 4848 }) {
4663 4849 return Object.fromEntries(
4664 4850 [
4665 4851 // Semantic color tokens
4666 - colorTokensCSS(computedColorRamps),
4852 + colorEntries,
4667 4853 // Legacy overrides
4668 4854 legacyWpAdminThemeOverridesCSS(primary),
4669 4855 legacyWpComponentsOverridesCSS
4670 4856 ].flat()
@@ -4669,8 +4855,35 @@
4669 4855 legacyWpComponentsOverridesCSS
4670 4856 ].flat()
4671 4857 );
4672 4858 }
4859 + function generateThemeProviderColors(primary, background) {
4860 + const seeds = {
4861 + ...DEFAULT_SEED_COLORS,
4862 + background,
4863 + primary
4864 + };
4865 + const computedColorRamps = /* @__PURE__ */ new Map();
4866 + const bgRamp = getCachedBgRamp(seeds.background);
4867 + for (const [rawRampName, seed] of Object.entries(seeds)) {
4868 + const rampName = rawRampName;
4869 + computedColorRamps.set(
4870 + rampName,
4871 + rampName === "background" ? bgRamp : getCachedAccentRamp(seed, bgRamp)
4872 + );
4873 + }
4874 + const colorEntries = colorTokensCSS(computedColorRamps);
4875 + return {
4876 + styles: generateStyles({
4877 + primary: seeds.primary,
4878 + colorEntries
4879 + }),
4880 + warnings: collectThemeProviderColorWarnings(
4881 + computedColorRamps,
4882 + new Map(colorEntries)
4883 + )
4884 + };
4885 + }
4673 4886 function useThemeProviderStyles({
4674 4887 color = {},
4675 4888 cursor,
4676 4889 cornerRadius
@@ -4675,10 +4888,11 @@
4675 4888 cursor,
4676 4889 cornerRadius
4677 4890 } = {}) {
4678 4891 const { resolvedSettings: inheritedSettings } = (0, import_element2.useContext)(ThemeContext);
4679 - const primary = color.primary ?? inheritedSettings.color?.primary ?? DEFAULT_SEED_COLORS.primary;
4680 - const background = color.background ?? inheritedSettings.color?.background ?? DEFAULT_SEED_COLORS.background;
4892 + const hasColor = color.primary !== void 0 || color.background !== void 0 || inheritedSettings.color?.primary !== void 0 || inheritedSettings.color?.background !== void 0;
4893 + const primary = hasColor ? color.primary ?? inheritedSettings.color?.primary ?? DEFAULT_SEED_COLORS.primary : void 0;
4894 + const background = hasColor ? color.background ?? inheritedSettings.color?.background ?? DEFAULT_SEED_COLORS.background : void 0;
4681 4895 const cursorControl = cursor?.control ?? inheritedSettings.cursor?.control;
4682 4896 const cornerRadiusPreset = cornerRadius ?? inheritedSettings.cornerRadius ?? "subtle";
4683 4897 const resolvedSettings = (0, import_element2.useMemo)(
4684 4898 () => ({
@@ -4690,43 +4904,30 @@
4690 4904 cornerRadius: cornerRadiusPreset
4691 4905 }),
4692 4906 [primary, background, cursorControl, cornerRadiusPreset]
4693 4907 );
4694 - const colorStyles = (0, import_element2.useMemo)(() => {
4695 - const seeds = {
4696 - ...DEFAULT_SEED_COLORS,
4697 - background,
4698 - primary
4699 - };
4700 - const computedColorRamps = /* @__PURE__ */ new Map();
4701 - const bgRamp = getCachedBgRamp(seeds.background);
4702 - Object.entries(seeds).forEach(([rampName, seed]) => {
4703 - if (rampName === "background") {
4704 - computedColorRamps.set("bg", bgRamp);
4705 - } else {
4706 - computedColorRamps.set(
4707 - rampName,
4708 - getCachedAccentRamp(seed, bgRamp)
4709 - );
4710 - }
4711 - });
4712 - return generateStyles({
4713 - primary: seeds.primary,
4714 - computedColorRamps
4715 - });
4908 + const generatedColors = (0, import_element2.useMemo)(() => {
4909 + if (primary === void 0 || background === void 0) {
4910 + return {
4911 + styles: {},
4912 + warnings: void 0
4913 + };
4914 + }
4915 + return generateThemeProviderColors(primary, background);
4716 4916 }, [primary, background]);
4717 4917 const themeProviderStyles = (0, import_element2.useMemo)(
4718 4918 () => ({
4719 - ...colorStyles,
4919 + ...generatedColors.styles,
4720 4920 ...cursorControl && {
4721 4921 "--wpds-cursor-control": cursorControl
4722 4922 }
4723 4923 }),
4724 - [colorStyles, cursorControl]
4924 + [generatedColors.styles, cursorControl]
4725 4925 );
4726 4926 return {
4727 4927 resolvedSettings,
4728 - themeProviderStyles
4928 + themeProviderStyles,
4929 + colorWarnings: generatedColors.warnings
4729 4930 };
4730 4931 }
4731 4932
4732 4933 // packages/theme/build-module/theme-provider.mjs
@@ -4811,11 +5012,11 @@
4811 5012 injectStyle(targetDocument, hash, css);
4812 5013 }
4813 5014 }
4814 5015 if (typeof process === "undefined" || true) {
4815 - registerStyle("f4e6e06c6a", ".dba930ea7a9438fd__root{display:contents}");
5016 + registerStyle("8d074a190c", "._0ebd6d9bf8b95794__wrapper{display:contents}");
4816 5017 }
4817 - var style_default = { "root": "dba930ea7a9438fd__root" };
5018 + var style_default = { "wrapper": "_0ebd6d9bf8b95794__wrapper" };
4818 5019 var rootProviderCountByDocument = /* @__PURE__ */ new WeakMap();
4819 5020 var ThemeProvider = ({
4820 5021 children,
4821 5022 color = {},
@@ -4820,16 +5021,18 @@
4820 5021 children,
4821 5022 color = {},
4822 5023 cursor,
4823 5024 cornerRadius,
4824 - isRoot = false
5025 + isRoot = false,
5026 + onColorWarnings
4825 5027 }) => {
4826 - const { themeProviderStyles, resolvedSettings } = useThemeProviderStyles({
5028 + const { themeProviderStyles, resolvedSettings, colorWarnings } = useThemeProviderStyles({
4827 5029 color,
4828 5030 cursor,
4829 5031 cornerRadius
4830 5032 });
4831 5033 const cornerRadiusPreset = resolvedSettings.cornerRadius ?? "subtle";
5034 + const onColorWarningsEvent = (0, import_compose.useEvent)(onColorWarnings);
4832 5035 const contextValue = (0, import_element3.useMemo)(
4833 5036 () => ({
4834 5037 resolvedSettings
4835 5038 }),
@@ -4835,8 +5038,13 @@
4835 5038 }),
4836 5039 [resolvedSettings]
4837 5040 );
4838 5041 const wrapperRef = (0, import_element3.useRef)(null);
5042 + (0, import_element3.useEffect)(() => {
5043 + if (colorWarnings !== void 0) {
5044 + onColorWarningsEvent(colorWarnings);
5045 + }
5046 + }, [colorWarnings, onColorWarningsEvent]);
4839 5047 (0, import_compose.useIsomorphicLayoutEffect)(() => {
4840 5048 if (!isRoot) {
4841 5049 return;
4842 5050 }
@@ -4855,8 +5063,16 @@
4855 5063 rootProviderCountByDocument.set(doc, active + 1);
4856 5064 }
4857 5065 const previous = /* @__PURE__ */ new Map();
4858 5066 const applied = [];
5067 + const previousRootProvider = root.getAttribute(
5068 + "data-wpds-root-provider"
5069 + );
5070 + const previousCornerRadius = root.getAttribute(
5071 + "data-wpds-corner-radius"
5072 + );
5073 + root.setAttribute("data-wpds-root-provider", "true");
5074 + root.setAttribute("data-wpds-corner-radius", cornerRadiusPreset);
4859 5075 for (const [rawKey, rawValue] of Object.entries(
4860 5076 themeProviderStyles
4861 5077 )) {
4862 5078 if (!rawKey.startsWith("--") || rawValue === null || rawValue === void 0) {
@@ -4882,10 +5098,26 @@
4882 5098 } else {
4883 5099 root.style.removeProperty(key);
4884 5100 }
4885 5101 }
5102 + if (previousRootProvider === null) {
5103 + root.removeAttribute("data-wpds-root-provider");
5104 + } else {
5105 + root.setAttribute(
5106 + "data-wpds-root-provider",
5107 + previousRootProvider
5108 + );
5109 + }
5110 + if (previousCornerRadius === null) {
5111 + root.removeAttribute("data-wpds-corner-radius");
5112 + } else {
5113 + root.setAttribute(
5114 + "data-wpds-corner-radius",
5115 + previousCornerRadius
5116 + );
5117 + }
4886 5118 };
4887 - }, [isRoot, themeProviderStyles]);
5119 + }, [cornerRadiusPreset, isRoot, themeProviderStyles]);
4888 5120 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4889 5121 "div",
4890 5122 {
4891 5123 ref: wrapperRef,
@@ -4890,9 +5122,9 @@
4890 5122 {
4891 5123 ref: wrapperRef,
4892 5124 "data-wpds-root-provider": isRoot || void 0,
4893 5125 "data-wpds-corner-radius": cornerRadiusPreset,
4894 - className: style_default.root,
5126 + className: style_default.wrapper,
4895 5127 style: themeProviderStyles,
4896 5128 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value: contextValue, children })
4897 5129 }
4898 5130 );
@@ -4922,6 +5154,8 @@
4922 5154 return useThemeProviderStyles;
4923 5155 }
4924 5156 });
4925 5157 return __toCommonJS(index_exports);
5158 +})();
5159 +(window.wp ||= {}).theme = wp.theme;
4926 5160 })();
4927 5161 //# sourceMappingURL=index.js.map