UNPKG

@activecollab/components

Version:

ActiveCollab Components

474 lines (468 loc) 15.8 kB
"use strict"; var _resizePolicy = require("./resizePolicy"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } var FREE = { proportional: false }; var start = function start(w, h) { var minW = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var minH = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; return (0, _resizePolicy.makeStart)({ w, h }, { w: minW, h: minH }); }; describe("clamp / snap", function () { it("clamps to the floor and, when given, the ceiling", function () { expect((0, _resizePolicy.clamp)(5, 10)).toBe(10); expect((0, _resizePolicy.clamp)(50, 10, 20)).toBe(20); expect((0, _resizePolicy.clamp)(15, 10, 20)).toBe(15); }); it("treats a missing ceiling as unbounded", function () { expect((0, _resizePolicy.clamp)(1e9, 10)).toBe(1e9); }); it("snaps to the nearest multiple, and passes through without a step", function () { expect((0, _resizePolicy.snap)(217, 8)).toBe(216); expect((0, _resizePolicy.snap)(220, 8)).toBe(224); expect((0, _resizePolicy.snap)(217)).toBe(217); expect((0, _resizePolicy.snap)(217, 0)).toBe(217); }); }); describe("effectiveBounds", function () { it("floors the policy minimum with the content minimum", function () { var bounds = (0, _resizePolicy.effectiveBounds)({ minW: 96, minH: 40, proportional: false }, { w: 160, h: 72 }); // The content wins on both axes here: a card may not be crushed below it. expect(bounds.wMin).toBe(160); expect(bounds.hMin).toBe(72); }); it("keeps the policy minimum when it is the higher of the two", function () { var bounds = (0, _resizePolicy.effectiveBounds)({ minW: 200, proportional: false }, { w: 160, h: 0 }); expect(bounds.wMin).toBe(200); }); it("reports an unset maximum as unbounded", function () { var bounds = (0, _resizePolicy.effectiveBounds)(FREE, { w: 0, h: 0 }); expect(bounds.wMax).toBe(Number.POSITIVE_INFINITY); expect(bounds.hMax).toBe(Number.POSITIVE_INFINITY); }); }); describe("applyResize — bounds", function () { it("stops at minW", function () { var policy = { minW: 180, proportional: false }; expect((0, _resizePolicy.applyResize)(start(300, 200), { dx: -500, dy: 0 }, policy).w).toBe(180); }); it("stops at maxW", function () { var policy = { maxW: 420, proportional: false }; expect((0, _resizePolicy.applyResize)(start(300, 200), { dx: +500, dy: 0 }, policy).w).toBe(420); }); it("stops at minH", function () { var policy = { minH: 120, proportional: false }; expect((0, _resizePolicy.applyResize)(start(300, 200), { dx: 0, dy: -500 }, policy).h).toBe(120); }); it("stops at maxH", function () { var policy = { maxH: 540, proportional: false }; expect((0, _resizePolicy.applyResize)(start(300, 200), { dx: 0, dy: +500 }, policy).h).toBe(540); }); it("leaves an unset bound unbounded", function () { // No maxW at all: a huge delta is applied in full. expect((0, _resizePolicy.applyResize)(start(300, 200), { dx: +5000, dy: 0 }, FREE).w).toBe(5300); // No minW either, so the floor is 0 rather than some implied width. expect((0, _resizePolicy.applyResize)(start(300, 200), { dx: -5000, dy: 0 }, FREE).w).toBe(0); }); it("lets the content minimum override a lower policy minimum", function () { var policy = { minW: 96, proportional: false }; var measured = (0, _resizePolicy.makeStart)({ w: 300, h: 200 }, { w: 160, h: 0 }); // 96 is the policy floor, but the content needs 160 — the higher wins. expect((0, _resizePolicy.applyResize)(measured, { dx: -500, dy: 0 }, policy).w).toBe(160); }); }); describe("applyResize — proportional", function () { /* The worked example from the spec: a proportional policy meeting a bound must not distort the ratio — the binding axis stops both. */ var policy = { minW: 96, maxW: 620, minH: 72, maxH: 540, proportional: true, step: 8 }; var proportionalStart = (0, _resizePolicy.makeStart)({ w: 300, h: 200 }, { w: 96, h: 72 }); it("holds the ratio when the WIDTH axis binds at the maximum", function () { // scaleMax = min(620/300, 540/200) = 2.066 → width binds expect((0, _resizePolicy.applyResize)(proportionalStart, { dx: +400, dy: 0 }, policy)).toEqual({ w: 620, h: 413 }); }); it("holds the ratio when the HEIGHT axis binds at the minimum", function () { // scaleMin = max(96/300, 72/200) = 0.36 → height binds expect((0, _resizePolicy.applyResize)(proportionalStart, { dx: -400, dy: 0 }, policy)).toEqual({ w: 108, h: 72 }); }); it("drives the scale from whichever axis the corner moved further", function () { var free = { proportional: true }; // A purely vertical drag scales the width too, so the corner is not // width-biased: +100 on a 200-tall card is a 1.5× scale. expect((0, _resizePolicy.applyResize)(start(300, 200), { dx: 0, dy: +100 }, free)).toEqual({ w: 450, h: 300 }); }); it("lets the grid yield rather than break the ratio at a bound", function () { // Snapping 108 to the 8px grid would give 112 — above the binding minimum. // The bound is a hard stop, so the card sits exactly on it instead. var result = (0, _resizePolicy.applyResize)(proportionalStart, { dx: -400, dy: 0 }, policy); expect(result.w % 8).not.toBe(0); expect(result.w).toBe(108); }); it("still snaps to the grid away from any bound", function () { var result = (0, _resizePolicy.applyResize)(proportionalStart, { dx: +37, dy: 0 }, policy); // 337 snaps to 336, and the height follows the same scale. expect(result).toEqual({ w: 336, h: 224 }); }); it("falls back to free-form when a side has no length to form a ratio", function () { // Width-only cards park a placeholder height; the ratio math must not // divide by zero. var result = (0, _resizePolicy.applyResize)((0, _resizePolicy.makeStart)({ w: 300, h: 0 }, { w: 0, h: 0 }), { dx: +40, dy: +40 }, { proportional: true }); expect(result.w).toBe(340); expect(Number.isNaN(result.h)).toBe(false); }); }); describe("applyResize — shift to constrain", function () { it("locks the ratio for one gesture on a free-form policy", function () { var result = (0, _resizePolicy.applyResize)(start(300, 200), { dx: +150, dy: 0 }, FREE, { constrain: true }); // 1.5× on both axes, from a purely horizontal drag. expect(result).toEqual({ w: 450, h: 300 }); }); it("leaves the axes independent without it", function () { expect((0, _resizePolicy.applyResize)(start(300, 200), { dx: +150, dy: 0 }, FREE)).toEqual({ w: 450, h: 200 }); }); it("changes nothing on a policy that is already proportional", function () { var policy = { proportional: true }; var delta = { dx: +150, dy: 0 }; expect((0, _resizePolicy.applyResize)(start(300, 200), delta, policy, { constrain: true })).toEqual((0, _resizePolicy.applyResize)(start(300, 200), delta, policy)); }); }); describe("applyResize — width-only axis", function () { /* The worked example from the spec: an auto-height card ignores the vertical component entirely. */ it("ignores the vertical component and holds the height", function () { var policy = { minW: 180, maxW: 420, proportional: false, step: 8 }; var result = (0, _resizePolicy.applyResize)((0, _resizePolicy.makeStart)({ w: 180, h: 240 }, { w: 180, h: 0 }), { dx: +37, dy: +200 }, policy, { axis: "width" }); expect(result).toEqual({ w: 216, h: 240 }); }); it("still lets the height follow the ratio in proportional mode", function () { // `axis: "width"` drops the pointer's vertical INPUT; it does not turn a // proportional card into a free-form one. var result = (0, _resizePolicy.applyResize)(start(300, 200), { dx: +150, dy: +999 }, { proportional: true }, { axis: "width" }); expect(result).toEqual({ w: 450, h: 300 }); }); }); describe("keyboardResize", function () { var policy = { minW: 180, maxW: 420, minH: 120, maxH: 400, proportional: false }; var contentMin = { w: 180, h: 120 }; var size = { w: 300, h: 200 }; it("nudges by the default step when the policy has none", function () { var _keyboardResize, _keyboardResize2, _keyboardResize3, _keyboardResize4; expect((_keyboardResize = (0, _resizePolicy.keyboardResize)("ArrowRight", size, policy, contentMin)) === null || _keyboardResize === void 0 ? void 0 : _keyboardResize.w).toBe(300 + _resizePolicy.DEFAULT_KEYBOARD_STEP); expect((_keyboardResize2 = (0, _resizePolicy.keyboardResize)("ArrowLeft", size, policy, contentMin)) === null || _keyboardResize2 === void 0 ? void 0 : _keyboardResize2.w).toBe(300 - _resizePolicy.DEFAULT_KEYBOARD_STEP); expect((_keyboardResize3 = (0, _resizePolicy.keyboardResize)("ArrowDown", size, policy, contentMin)) === null || _keyboardResize3 === void 0 ? void 0 : _keyboardResize3.h).toBe(200 + _resizePolicy.DEFAULT_KEYBOARD_STEP); expect((_keyboardResize4 = (0, _resizePolicy.keyboardResize)("ArrowUp", size, policy, contentMin)) === null || _keyboardResize4 === void 0 ? void 0 : _keyboardResize4.h).toBe(200 - _resizePolicy.DEFAULT_KEYBOARD_STEP); }); it("nudges by the policy step when there is one", function () { var _keyboardResize5; expect((_keyboardResize5 = (0, _resizePolicy.keyboardResize)("ArrowRight", size, _objectSpread(_objectSpread({}, policy), {}, { step: 20 }), contentMin)) === null || _keyboardResize5 === void 0 ? void 0 : _keyboardResize5.w).toBe(320); }); it("makes Shift a coarse nudge", function () { var _keyboardResize6; expect((_keyboardResize6 = (0, _resizePolicy.keyboardResize)("ArrowRight", size, policy, contentMin, { shiftKey: true })) === null || _keyboardResize6 === void 0 ? void 0 : _keyboardResize6.w).toBe(300 + _resizePolicy.DEFAULT_KEYBOARD_STEP * _resizePolicy.SHIFT_STEP_MULTIPLIER); }); it("clamps a nudge exactly like the pointer does", function () { var _keyboardResize7; expect((_keyboardResize7 = (0, _resizePolicy.keyboardResize)("ArrowLeft", { w: 184, h: 200 }, policy, contentMin, { shiftKey: true })) === null || _keyboardResize7 === void 0 ? void 0 : _keyboardResize7.w).toBe(180); }); it("jumps to the minimum on Home and the maximum on End", function () { expect((0, _resizePolicy.keyboardResize)("Home", size, policy, contentMin)).toEqual({ w: 180, h: 120 }); expect((0, _resizePolicy.keyboardResize)("End", size, policy, contentMin)).toEqual({ w: 420, h: 400 }); }); it("leaves an axis with no maximum where it is on End", function () { var unbounded = { minW: 180, maxW: 420, proportional: false }; expect((0, _resizePolicy.keyboardResize)("End", size, unbounded, { w: 180, h: 0 })).toEqual({ w: 420, h: 200 }); }); it("leaves an axis with no minimum where it is on Home", function () { // Nobody asked for a floor on either axis, so Home has nothing to jump to — // it must not collapse the card to zero. expect((0, _resizePolicy.keyboardResize)("Home", size, FREE, { w: 0, h: 0 })).toEqual(size); }); it("ignores the vertical keys on a width-only card", function () { expect((0, _resizePolicy.keyboardResize)("ArrowUp", size, policy, contentMin, { axis: "width" })).toBeNull(); expect((0, _resizePolicy.keyboardResize)("ArrowDown", size, policy, contentMin, { axis: "width" })).toBeNull(); }); it("holds the height on a width-only Home and End", function () { expect((0, _resizePolicy.keyboardResize)("Home", size, policy, contentMin, { axis: "width" })).toEqual({ w: 180, h: 200 }); expect((0, _resizePolicy.keyboardResize)("End", size, policy, contentMin, { axis: "width" })).toEqual({ w: 420, h: 200 }); }); it("returns null for a key it does not own", function () { expect((0, _resizePolicy.keyboardResize)("Enter", size, policy, contentMin)).toBeNull(); expect((0, _resizePolicy.keyboardResize)("a", size, policy, contentMin)).toBeNull(); }); }); describe("isResizeKey", function () { it("owns the arrows plus Home and End, and nothing else", function () { _resizePolicy.RESIZE_KEYS.forEach(function (key) { return expect((0, _resizePolicy.isResizeKey)(key)).toBe(true); }); expect((0, _resizePolicy.isResizeKey)("Enter")).toBe(false); expect((0, _resizePolicy.isResizeKey)("Tab")).toBe(false); }); }); describe("measurePercent", function () { var policy = { minW: 200, maxW: 400, proportional: false }; var contentMin = { w: 0, h: 0 }; it("reports the width axis as a percent of its allowed range", function () { expect((0, _resizePolicy.measurePercent)({ w: 200, h: 0 }, policy, contentMin)).toBe(0); expect((0, _resizePolicy.measurePercent)({ w: 300, h: 0 }, policy, contentMin)).toBe(50); expect((0, _resizePolicy.measurePercent)({ w: 400, h: 0 }, policy, contentMin)).toBe(100); }); it("stays inside 0–100 for a size outside the bounds", function () { expect((0, _resizePolicy.measurePercent)({ w: 40, h: 0 }, policy, contentMin)).toBe(0); expect((0, _resizePolicy.measurePercent)({ w: 900, h: 0 }, policy, contentMin)).toBe(100); }); it("reports 0 when the range is not finite", function () { expect((0, _resizePolicy.measurePercent)({ w: 300, h: 0 }, FREE, contentMin)).toBe(0); }); }); //# sourceMappingURL=resizePolicy.test.js.map