Files
NODEDC_DESIGN_GUIDELINE/scripts/range-control-contract.test.mjs
T

62 lines
3.4 KiB
JavaScript

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import test from "node:test";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { RangeControl } from "../packages/ui-react/dist/index.js";
test("RangeControl keeps native drag semantics and exposes one persistent exact-value editor", () => {
const markup = renderToStaticMarkup(createElement(RangeControl, {
label: "Размер головки",
value: 20,
min: 1,
max: 32,
step: 1,
formatValue: (value) => `${value} px`,
onChange: () => {},
}));
assert.match(markup, /type="range"/);
assert.match(markup, /aria-valuetext="20 px"/);
assert.match(markup, /class="nodedc-range__editor"/);
assert.match(markup, /aria-label="Размер головки: точное значение"/);
assert.doesNotMatch(markup, /nodedc-range__value-hit/);
});
test("exact editing is a stable native caret field without remount, forced selection or a dark editor box", async () => {
const [component, styles, windowComponent] = await Promise.all([
readFile(new URL("../packages/ui-react/src/RangeControl.tsx", import.meta.url), "utf8"),
readFile(new URL("../packages/ui-core/styles.css", import.meta.url), "utf8"),
readFile(new URL("../packages/ui-react/src/Window.tsx", import.meta.url), "utf8"),
]);
assert.match(component, /exactValueBounds\?: \{/);
assert.match(component, /exactValueBounds\?\.min \?\? Number\.NEGATIVE_INFINITY/);
assert.match(component, /exactValueBounds\?\.max \?\? Number\.POSITIVE_INFINITY/);
assert.match(component, /normalizeEditedRangeValue\(parsed, min, max, step, exactValueBounds\)/);
assert.match(component, /value=\{draft\}/);
assert.match(component, /data-contrast=\{editorContrast\}/);
assert.match(component, /fillRight >= textRight \? "fill" : "base"/);
assert.match(component, /new ResizeObserver\(updateContrast\)/);
const editorSource = component.match(/className="nodedc-range__editor"[\s\S]*?onBlur=\{\(\) => \{[\s\S]*?\n \}\}\n \/>/)?.[0] ?? "";
assert.notEqual(editorSource, "");
assert.doesNotMatch(editorSource, /onPointerDown=/);
assert.match(component, /event\.key === "Enter"/);
assert.match(component, /event\.key === "Escape"/);
assert.match(component, /event\.stopPropagation\(\)/);
assert.match(component, /cancelNextBlurRef/);
assert.match(component, /event\.currentTarget\.blur\(\)/);
assert.match(component, /onBlur=\{\(\) => \{/);
assert.doesNotMatch(component, /\.select\(\)/);
assert.doesNotMatch(component, /setSelectionRange/);
assert.doesNotMatch(component, /\{editing \? \(\s*<input/);
assert.match(styles, /\.nodedc-range input\[type="range"\][\s\S]*?z-index: 4/);
assert.match(styles, /\.nodedc-range__editor[\s\S]*?z-index: 5[\s\S]*?background: transparent[\s\S]*?color: transparent[\s\S]*?caret-color: transparent[\s\S]*?box-shadow: none/);
assert.match(styles, /\.nodedc-range__editor\[data-active\][\s\S]*?caret-color: currentColor/);
assert.match(styles, /\.nodedc-range__editor\[data-active\]\[data-contrast="fill"\][\s\S]*?rgb\(var\(--nodedc-on-accent-rgb\)\)/);
assert.match(windowComponent, /const onCloseRef = useRef\(onClose\)/);
assert.match(windowComponent, /onCloseRef\.current = onClose/);
assert.match(windowComponent, /onCloseRef\.current\(\)/);
assert.doesNotMatch(windowComponent, /\[closeOnEscape, onClose, open, shouldLockBodyScroll, shouldTrapFocus\]/);
});