@jsenv/dom 0.10.1 → 0.10.2
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/jsenv_dom.js +90 -41
- package/package.json +1 -1
package/dist/jsenv_dom.js
CHANGED
|
@@ -2084,6 +2084,9 @@ const normalizeStyle = (
|
|
|
2084
2084
|
if (propertyName === "transform") {
|
|
2085
2085
|
if (context === "js") {
|
|
2086
2086
|
if (typeof value === "string") {
|
|
2087
|
+
if (isCSSKeyword(value)) {
|
|
2088
|
+
return value;
|
|
2089
|
+
}
|
|
2087
2090
|
// For js context, prefer objects
|
|
2088
2091
|
return parseCSSTransform(value, normalizeStyle);
|
|
2089
2092
|
}
|
|
@@ -2121,6 +2124,9 @@ const normalizeStyle = (
|
|
|
2121
2124
|
if (propertyName === "background") {
|
|
2122
2125
|
if (context === "js") {
|
|
2123
2126
|
if (typeof value === "string") {
|
|
2127
|
+
if (isCSSKeyword(value)) {
|
|
2128
|
+
return value;
|
|
2129
|
+
}
|
|
2124
2130
|
// For js context, prefer objects
|
|
2125
2131
|
return parseCSSBackground(value, {
|
|
2126
2132
|
parseStyle,
|
|
@@ -2158,6 +2164,9 @@ const normalizeStyle = (
|
|
|
2158
2164
|
if (propertyName === "border") {
|
|
2159
2165
|
if (context === "js") {
|
|
2160
2166
|
if (typeof value === "string") {
|
|
2167
|
+
if (isCSSKeyword(value)) {
|
|
2168
|
+
return value;
|
|
2169
|
+
}
|
|
2161
2170
|
// For js context, prefer objects
|
|
2162
2171
|
return parseCSSBorder(value, element);
|
|
2163
2172
|
}
|
|
@@ -2285,10 +2294,20 @@ const normalizeStyle = (
|
|
|
2285
2294
|
}
|
|
2286
2295
|
|
|
2287
2296
|
if (colorPropertySet.has(propertyName)) {
|
|
2288
|
-
if (typeof value === "string"
|
|
2289
|
-
|
|
2297
|
+
if (typeof value === "string") {
|
|
2298
|
+
if (isCSSKeyword(value)) {
|
|
2299
|
+
return value;
|
|
2300
|
+
}
|
|
2301
|
+
if (isCSSFunction(value)) {
|
|
2302
|
+
return value;
|
|
2303
|
+
}
|
|
2290
2304
|
}
|
|
2291
2305
|
const rgba = parseCSSColor(value, element);
|
|
2306
|
+
if (rgba === null) {
|
|
2307
|
+
// parseCSSColor could not parse the value (e.g. a CSS variable or unknown keyword)
|
|
2308
|
+
// return as-is so the original string reaches the DOM unchanged
|
|
2309
|
+
return value;
|
|
2310
|
+
}
|
|
2292
2311
|
if (context === "js") {
|
|
2293
2312
|
return rgba;
|
|
2294
2313
|
}
|
|
@@ -2307,6 +2326,9 @@ const stringifyStyle = (value, propertyName, element) => {
|
|
|
2307
2326
|
const isCSSFunction = (value) => {
|
|
2308
2327
|
return /^[a-z-]+\(/.test(value);
|
|
2309
2328
|
};
|
|
2329
|
+
const isCSSKeyword = (value) => {
|
|
2330
|
+
return globalCSSKeywordSet.has(value);
|
|
2331
|
+
};
|
|
2310
2332
|
const normalizeNumber = (value, { unit, propertyName, preferedType }) => {
|
|
2311
2333
|
if (typeof value === "string") {
|
|
2312
2334
|
// CSS variables and CSS functions like calc() must be passed through as-is
|
|
@@ -3406,74 +3428,101 @@ const isSameColor = (color1, color2) => {
|
|
|
3406
3428
|
|
|
3407
3429
|
/**
|
|
3408
3430
|
* Returns `"white"` or `"black"`, whichever provides better contrast against
|
|
3409
|
-
* the given background color
|
|
3431
|
+
* the given background color, using OKLCH lightness (perceptually uniform).
|
|
3410
3432
|
*
|
|
3411
|
-
*
|
|
3433
|
+
* Uses a threshold of 0.5 on the OKLCH L axis (0–1 scale).
|
|
3434
|
+
* Colors with L > threshold are considered light → return "black".
|
|
3435
|
+
* Colors with L ≤ threshold are considered dark → return "white".
|
|
3412
3436
|
*
|
|
3413
3437
|
* @param {string} backgroundColor - CSS color value (hex, rgb, hsl, CSS variable, …)
|
|
3414
3438
|
* @param {Element} [element] - DOM element used to resolve CSS variables / computed styles
|
|
3439
|
+
* @param {number} [lightnessThreshold=0.5] - OKLCH L threshold (0–1). Below → "white", above → "black".
|
|
3415
3440
|
* @returns {"white"|"black"}
|
|
3416
3441
|
* @example
|
|
3417
|
-
* contrastColor("#1a202c")
|
|
3418
|
-
* contrastColor("#f5f5f5")
|
|
3419
|
-
* contrastColor("
|
|
3442
|
+
* contrastColor("#1a202c") // "white" (dark background)
|
|
3443
|
+
* contrastColor("#f5f5f5") // "black" (light background)
|
|
3444
|
+
* contrastColor("#e91e8c") // "white" (vivid pink, perceptually dark)
|
|
3420
3445
|
*/
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3446
|
+
const contrastColor = (
|
|
3447
|
+
backgroundColor,
|
|
3448
|
+
element,
|
|
3449
|
+
lightnessThreshold = 0.5,
|
|
3450
|
+
) => {
|
|
3424
3451
|
const resolvedBgColor = parseCSSColor(backgroundColor, element);
|
|
3425
3452
|
if (!resolvedBgColor) {
|
|
3426
3453
|
return "white";
|
|
3427
3454
|
}
|
|
3428
|
-
|
|
3429
|
-
// Composite against white when the background has transparency so the
|
|
3430
|
-
// luminance reflects what the user actually sees.
|
|
3431
3455
|
const [r, g, b] =
|
|
3432
3456
|
resolvedBgColor[3] === 1
|
|
3433
3457
|
? resolvedBgColor
|
|
3434
3458
|
: compositeColor(resolvedBgColor, WHITE_RGBA);
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
// One luminance comparison replaces two full contrast-ratio computations.
|
|
3439
|
-
// White wins (or ties) when bgLuminance <= the crossover point where both
|
|
3440
|
-
// colors yield identical ratios:
|
|
3441
|
-
// contrastWithWhite = contrastWithBlack
|
|
3442
|
-
// 1.05 / (L + 0.05) = (L + 0.05) / 0.05
|
|
3443
|
-
// L = √(1.05 × 0.05) − 0.05 ≈ 0.179
|
|
3444
|
-
return bgLuminance <= EQUAL_CONTRAST_LUMINANCE ? "white" : "black";
|
|
3459
|
+
const L = rgbToOklchL(r, g, b);
|
|
3460
|
+
return L <= lightnessThreshold ? "white" : "black";
|
|
3445
3461
|
};
|
|
3446
3462
|
|
|
3447
|
-
// Luminance threshold at which white and black yield the same contrast ratio
|
|
3448
|
-
// against a background. Below → white wins or ties; above → black wins.
|
|
3449
|
-
const EQUAL_CONTRAST_LUMINANCE = Math.sqrt(1.05 * 0.05) - 0.05;
|
|
3450
|
-
const WHITE_RGBA = [255, 255, 255, 1];
|
|
3451
|
-
|
|
3452
3463
|
/**
|
|
3453
|
-
* Resolves the
|
|
3464
|
+
* Resolves the OKLCH lightness of a CSS color (perceptually uniform, 0–1 scale).
|
|
3465
|
+
*
|
|
3454
3466
|
* @param {string} color - CSS color value (hex, rgb, hsl, CSS variable, etc.)
|
|
3455
3467
|
* @param {Element} [element] - DOM element to resolve CSS variables against
|
|
3456
|
-
* @returns {number|
|
|
3468
|
+
* @returns {number|null} OKLCH L value (0–1), or null if color cannot be resolved
|
|
3457
3469
|
* @example
|
|
3458
|
-
* //
|
|
3459
|
-
*
|
|
3460
|
-
*
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3470
|
+
* resolveOklchLightness("#e91e8c") // ~0.56 (vivid pink feels medium-bright)
|
|
3471
|
+
* resolveOklchLightness("#4476ff") // ~0.53 (blue)
|
|
3472
|
+
* resolveOklchLightness("#1a202c") // ~0.22 (dark background)
|
|
3473
|
+
*/
|
|
3474
|
+
const resolveOklchLightness = (color, element) => {
|
|
3475
|
+
const rgba = parseCSSColor(color, element);
|
|
3476
|
+
if (!rgba) {
|
|
3477
|
+
return null;
|
|
3478
|
+
}
|
|
3479
|
+
const [r, g, b] = rgba;
|
|
3480
|
+
return rgbToOklchL(r, g, b);
|
|
3481
|
+
};
|
|
3482
|
+
|
|
3483
|
+
/**
|
|
3484
|
+
* Resolves the WCAG relative luminance of a CSS color (kept for backwards compatibility).
|
|
3485
|
+
* @deprecated Prefer resolveOklchLightness for perceptually uniform results.
|
|
3467
3486
|
*/
|
|
3468
3487
|
const resolveColorLuminance = (color, element) => {
|
|
3469
3488
|
const rgba = parseCSSColor(color, element);
|
|
3470
3489
|
if (!rgba) {
|
|
3471
|
-
return
|
|
3490
|
+
return null;
|
|
3472
3491
|
}
|
|
3473
3492
|
const [r, g, b] = rgba;
|
|
3474
3493
|
return getLuminance(r, g, b);
|
|
3475
3494
|
};
|
|
3476
3495
|
|
|
3496
|
+
const WHITE_RGBA = [255, 255, 255, 1];
|
|
3497
|
+
|
|
3498
|
+
/**
|
|
3499
|
+
* Converts sRGB (0–255 each) to OKLCH lightness L (0–1).
|
|
3500
|
+
* Implements the sRGB → Linear sRGB → XYZ D65 → OKLab → L pipeline.
|
|
3501
|
+
*/
|
|
3502
|
+
const rgbToOklchL = (r, g, b) => {
|
|
3503
|
+
// sRGB → linear
|
|
3504
|
+
const toLinear = (c) => {
|
|
3505
|
+
c = c / 255;
|
|
3506
|
+
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
3507
|
+
};
|
|
3508
|
+
const lr = toLinear(r);
|
|
3509
|
+
const lg = toLinear(g);
|
|
3510
|
+
const lb = toLinear(b);
|
|
3511
|
+
|
|
3512
|
+
// Linear sRGB → LMS (Oklab M1 matrix)
|
|
3513
|
+
const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;
|
|
3514
|
+
const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;
|
|
3515
|
+
const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;
|
|
3516
|
+
|
|
3517
|
+
// Cube root
|
|
3518
|
+
const l_ = Math.cbrt(l);
|
|
3519
|
+
const m_ = Math.cbrt(m);
|
|
3520
|
+
const s_ = Math.cbrt(s);
|
|
3521
|
+
|
|
3522
|
+
// LMS → OKLab L
|
|
3523
|
+
return 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
|
|
3524
|
+
};
|
|
3525
|
+
|
|
3477
3526
|
/**
|
|
3478
3527
|
* Calculates the contrast ratio between two RGBA colors
|
|
3479
3528
|
* Based on WCAG 2.1 specification
|
|
@@ -13184,4 +13233,4 @@ const useResizeStatus = (elementRef, { as = "number" } = {}) => {
|
|
|
13184
13233
|
};
|
|
13185
13234
|
};
|
|
13186
13235
|
|
|
13187
|
-
export { EASING, activeElementSignal, addActiveElementEffect, addAttributeEffect, allowWheelThrough, appendStyles, canInterceptKeys, captureScrollState, contrastColor, createBackgroundColorTransition, createBackgroundTransition, createBorderRadiusTransition, createBorderTransition, createDragGestureController, createDragToMoveGestureController, createGroupTransitionController, createHeightTransition, createIterableWeakSet, createOpacityTransition, createPubSub, createStyleController, createTimelineTransition, createTransition, createTranslateXTransition, createValueEffect, createWidthTransition, cubicBezier, dragAfterThreshold, elementIsFocusable, elementIsVisibleForFocus, elementIsVisuallyVisible, findAfter, findAncestor, findBefore, findDescendant, findFocusable, getAvailableHeight, getAvailableWidth, getBackground, getBackgroundColor, getBorder, getBorderRadius, getBorderSizes, getContrastRatio, getDefaultStyles, getDragCoordinates, getDropTargetInfo, getElementSignature, getFirstVisuallyVisibleAncestor, getFocusVisibilityInfo, getHeight, getHeightWithoutTransition, getInnerHeight, getInnerWidth, getLuminance, getMarginSizes, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getOpacity, getOpacityWithoutTransition, getPaddingSizes, getPositionedParent, getPreferedColorScheme, getScrollBox, getScrollContainer, getScrollContainerSet, getScrollRelativeRect, getSelfAndAncestorScrolls, getStyle, getTranslateX, getTranslateXWithoutTransition, getTranslateY, getVisuallyVisibleInfo, getWidth, getWidthWithoutTransition, hasCSSSizeUnit, initFlexDetailsSet, initFocusGroup, initPositionSticky, isSameColor, isScrollable, measureScrollbar, mergeOneStyle, mergeTwoStyles, normalizeStyles, parseStyle, pickPositionRelativeTo, prefersDarkColors, prefersLightColors, preventFocusNav, preventFocusNavViaKeyboard, preventIntermediateScrollbar, resolveCSSColor, resolveCSSSize, resolveColorLuminance, scrollIntoViewScoped, scrollIntoViewWithStickyAwareness, setAttribute, setAttributes, setStyles, startDragToResizeGesture, stickyAsRelativeCoords, stringifyStyle, trapFocusInside, trapScrollInside, useActiveElement, useAvailableHeight, useAvailableWidth, useMaxHeight, useMaxWidth, useResizeStatus, visibleRectEffect };
|
|
13236
|
+
export { EASING, activeElementSignal, addActiveElementEffect, addAttributeEffect, allowWheelThrough, appendStyles, canInterceptKeys, captureScrollState, contrastColor, createBackgroundColorTransition, createBackgroundTransition, createBorderRadiusTransition, createBorderTransition, createDragGestureController, createDragToMoveGestureController, createGroupTransitionController, createHeightTransition, createIterableWeakSet, createOpacityTransition, createPubSub, createStyleController, createTimelineTransition, createTransition, createTranslateXTransition, createValueEffect, createWidthTransition, cubicBezier, dragAfterThreshold, elementIsFocusable, elementIsVisibleForFocus, elementIsVisuallyVisible, findAfter, findAncestor, findBefore, findDescendant, findFocusable, getAvailableHeight, getAvailableWidth, getBackground, getBackgroundColor, getBorder, getBorderRadius, getBorderSizes, getContrastRatio, getDefaultStyles, getDragCoordinates, getDropTargetInfo, getElementSignature, getFirstVisuallyVisibleAncestor, getFocusVisibilityInfo, getHeight, getHeightWithoutTransition, getInnerHeight, getInnerWidth, getLuminance, getMarginSizes, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getOpacity, getOpacityWithoutTransition, getPaddingSizes, getPositionedParent, getPreferedColorScheme, getScrollBox, getScrollContainer, getScrollContainerSet, getScrollRelativeRect, getSelfAndAncestorScrolls, getStyle, getTranslateX, getTranslateXWithoutTransition, getTranslateY, getVisuallyVisibleInfo, getWidth, getWidthWithoutTransition, hasCSSSizeUnit, initFlexDetailsSet, initFocusGroup, initPositionSticky, isSameColor, isScrollable, measureScrollbar, mergeOneStyle, mergeTwoStyles, normalizeStyles, parseStyle, pickPositionRelativeTo, prefersDarkColors, prefersLightColors, preventFocusNav, preventFocusNavViaKeyboard, preventIntermediateScrollbar, resolveCSSColor, resolveCSSSize, resolveColorLuminance, resolveOklchLightness, scrollIntoViewScoped, scrollIntoViewWithStickyAwareness, setAttribute, setAttributes, setStyles, startDragToResizeGesture, stickyAsRelativeCoords, stringifyStyle, trapFocusInside, trapScrollInside, useActiveElement, useAvailableHeight, useAvailableWidth, useMaxHeight, useMaxWidth, useResizeStatus, visibleRectEffect };
|