@tenphi/glaze 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1087,6 +1087,15 @@ const APCA_PRESETS = {
1087
1087
  min: 15
1088
1088
  };
1089
1089
  /**
1090
+ * APCA-W3 "Enhanced Level" delta added to a bare APCA target in high-contrast
1091
+ * mode when no explicit HC value is provided (analogous to WCAG AAA over AA).
1092
+ * Only applied when neither the outer `contrast` pair nor the inner `apca`
1093
+ * pair carries an explicit HC entry.
1094
+ */
1095
+ const APCA_HC_ENHANCEMENT = 15;
1096
+ /** Upper bound for an APCA Lc target after HC enhancement. */
1097
+ const APCA_MAX_LC = 106;
1098
+ /**
1090
1099
  * Resolve an APCA target — a raw Lc number (kept as-is) or an `ApcaPreset`
1091
1100
  * keyword mapped to its Lc value. The magnitude is forced non-negative.
1092
1101
  */
@@ -1100,10 +1109,35 @@ const CONTRAST_PRESETS = {
1100
1109
  "AA-large": 3,
1101
1110
  "AAA-large": 4.5
1102
1111
  };
1112
+ /**
1113
+ * WCAG high-contrast auto-promotion (analog of APCA's Enhanced Level). A bare
1114
+ * AA / AA-large preset is promoted to its spec-defined "Enhanced" successor
1115
+ * (SC 1.4.3 → SC 1.4.6) in high-contrast mode. AAA / AAA-large are already
1116
+ * the top WCAG tier and are left unchanged. Bare numeric targets have no
1117
+ * defined successor tier and are also left unchanged. An explicit HC value
1118
+ * (outer or inner pair) always overrides.
1119
+ */
1120
+ const WCAG_HC_PROMOTION = {
1121
+ AA: "AAA",
1122
+ "AA-large": "AAA-large"
1123
+ };
1103
1124
  function resolveMinContrast(value) {
1104
1125
  if (typeof value === "number") return Math.max(1, value);
1105
1126
  return CONTRAST_PRESETS[value];
1106
1127
  }
1128
+ /**
1129
+ * Resolve a WCAG target (number or preset) for a mode, applying the
1130
+ * high-contrast auto-promotion when `explicitHC` is false and the value is an
1131
+ * AA-family preset. Bare numbers and AAA-family presets pass through.
1132
+ */
1133
+ function resolveWcagTarget(value, isHighContrast, explicitHC) {
1134
+ if (typeof value === "number") return resolveMinContrast(value);
1135
+ if (isHighContrast && !explicitHC) {
1136
+ const promoted = WCAG_HC_PROMOTION[value];
1137
+ if (promoted !== void 0) return resolveMinContrast(promoted);
1138
+ }
1139
+ return resolveMinContrast(value);
1140
+ }
1107
1141
  function pickPair(p, isHighContrast) {
1108
1142
  return Array.isArray(p) ? isHighContrast ? p[1] : p[0] : p;
1109
1143
  }
@@ -1112,20 +1146,35 @@ function pickPair(p, isHighContrast) {
1112
1146
  * given mode into `{ metric, target }`. Handles the inner metric HC pair and
1113
1147
  * preset resolution. `polarity` is passed through to the result for the APCA
1114
1148
  * branch (it controls argument order in the solver); WCAG ignores it.
1115
- */
1116
- function resolveContrastForMode(spec, isHighContrast, polarity) {
1149
+ *
1150
+ * `outerExplicitHC` indicates whether the caller selected this `spec` from an
1151
+ * explicit high-contrast entry of the outer `contrast` pair. Together with the
1152
+ * inner metric pair, it decides whether the HC auto-enhancement fires:
1153
+ * - APCA: +15 Lc "Enhanced Level" boost when neither level is explicit.
1154
+ * - WCAG: AA → AAA / AA-large → AAA-large promotion (SC 1.4.3 → 1.4.6) when
1155
+ * neither level is explicit. AAA-family presets and bare numbers are left
1156
+ * unchanged (AAA is the top WCAG tier).
1157
+ * Defaults to `false` (correct for direct callers, which pass a single
1158
+ * selected spec rather than an outer pair).
1159
+ */
1160
+ function resolveContrastForMode(spec, isHighContrast, polarity, outerExplicitHC) {
1117
1161
  if (typeof spec === "number" || typeof spec === "string") return {
1118
1162
  metric: "wcag",
1119
- target: resolveMinContrast(spec)
1120
- };
1121
- if ("apca" in spec) return {
1122
- metric: "apca",
1123
- target: resolveApcaTarget(pickPair(spec.apca, isHighContrast)),
1124
- polarity: polarity ?? "fg"
1163
+ target: resolveWcagTarget(spec, isHighContrast, !!outerExplicitHC)
1125
1164
  };
1165
+ if ("apca" in spec) {
1166
+ const baseTarget = resolveApcaTarget(pickPair(spec.apca, isHighContrast));
1167
+ const innerExplicitHC = Array.isArray(spec.apca);
1168
+ return {
1169
+ metric: "apca",
1170
+ target: isHighContrast && !outerExplicitHC && !innerExplicitHC ? Math.min(baseTarget + APCA_HC_ENHANCEMENT, APCA_MAX_LC) : baseTarget,
1171
+ polarity: polarity ?? "fg"
1172
+ };
1173
+ }
1174
+ const innerExplicitHC = Array.isArray(spec.wcag);
1126
1175
  return {
1127
1176
  metric: "wcag",
1128
- target: resolveMinContrast(pickPair(spec.wcag, isHighContrast))
1177
+ target: resolveWcagTarget(pickPair(spec.wcag, isHighContrast), isHighContrast, !!outerExplicitHC || innerExplicitHC)
1129
1178
  };
1130
1179
  }
1131
1180
  const APCA_EXPONENTS = {
@@ -1827,7 +1876,8 @@ function resolveRole(name, def, ctx) {
1827
1876
  return resolveRoleInMap(name, def, ctx.defs, ctx.config.inferRole, ctx.roles);
1828
1877
  }
1829
1878
  function resolveContrastSpec(spec, isHighContrast, polarity) {
1830
- return resolveContrastForMode(isHighContrast ? pairHC(spec) : pairNormal(spec), isHighContrast, polarity);
1879
+ const outerExplicitHC = Array.isArray(spec);
1880
+ return resolveContrastForMode(isHighContrast ? pairHC(spec) : pairNormal(spec), isHighContrast, polarity, outerExplicitHC);
1831
1881
  }
1832
1882
  /**
1833
1883
  * Apply the relative-tone delta against a base, honoring `flip`.
@@ -3719,6 +3769,9 @@ glaze.resetConfig = function resetConfig$1() {
3719
3769
  };
3720
3770
 
3721
3771
  //#endregion
3772
+ exports.APCA_HC_ENHANCEMENT = APCA_HC_ENHANCEMENT;
3773
+ exports.APCA_MAX_LC = APCA_MAX_LC;
3774
+ exports.APCA_PRESETS = APCA_PRESETS;
3722
3775
  exports.REF_EPS = REF_EPS;
3723
3776
  exports.apcaContrast = apcaContrast;
3724
3777
  exports.assertAllPastel = assertAllPastel;