@pie-lib/mask-markup 3.1.3 → 4.0.0-next.37
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/_virtual/_rolldown/runtime.js +4 -0
- package/dist/choices/choice.d.ts +28 -0
- package/dist/choices/choice.js +92 -0
- package/dist/choices/index.d.ts +29 -0
- package/dist/choices/index.js +59 -0
- package/dist/componentize.d.ts +12 -0
- package/dist/componentize.js +4 -0
- package/dist/components/blank.d.ts +45 -0
- package/dist/components/blank.js +273 -0
- package/dist/components/correct-input.d.ts +11 -0
- package/dist/components/dropdown.d.ts +37 -0
- package/dist/components/dropdown.js +311 -0
- package/dist/components/input.d.ts +37 -0
- package/dist/constructed-response.d.ts +44 -0
- package/dist/constructed-response.js +56 -0
- package/dist/customizable.d.ts +43 -0
- package/dist/customizable.js +8 -0
- package/dist/drag-in-the-blank.d.ts +47 -0
- package/dist/drag-in-the-blank.js +220 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +7 -0
- package/dist/inline-dropdown.d.ts +44 -0
- package/dist/inline-dropdown.js +24 -0
- package/dist/keyboard-coordinates.d.ts +25 -0
- package/dist/keyboard-coordinates.js +49 -0
- package/dist/mask.d.ts +30 -0
- package/dist/mask.js +95 -0
- package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +16 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/index.js +17 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/cssPrefix.js +9 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/cssUnitless.js +26 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/hasOwn.js +11 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/isFunction.js +11 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/isObject.js +11 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/prefixInfo.js +24 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/prefixProperties.js +32 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/prefixer.js +29 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/camelize.js +14 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/hyphenRe.js +8 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/hyphenate.js +12 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/separate.js +11 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/toLowerFirst.js +10 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/toUpperFirst.js +10 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/toStyleObject.js +55 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/toStyleString.js +16 -0
- package/dist/serialization.d.ts +34 -0
- package/dist/serialization.js +132 -0
- package/dist/with-mask.d.ts +55 -0
- package/dist/with-mask.js +45 -0
- package/package.json +35 -19
- package/CHANGELOG.json +0 -17
- package/CHANGELOG.md +0 -1353
- package/LICENSE.md +0 -5
- package/lib/choices/choice.js +0 -138
- package/lib/choices/choice.js.map +0 -1
- package/lib/choices/index.js +0 -126
- package/lib/choices/index.js.map +0 -1
- package/lib/componentize.js +0 -21
- package/lib/componentize.js.map +0 -1
- package/lib/components/blank.js +0 -489
- package/lib/components/blank.js.map +0 -1
- package/lib/components/correct-input.js +0 -94
- package/lib/components/correct-input.js.map +0 -1
- package/lib/components/dropdown.js +0 -480
- package/lib/components/dropdown.js.map +0 -1
- package/lib/components/input.js +0 -50
- package/lib/components/input.js.map +0 -1
- package/lib/constructed-response.js +0 -101
- package/lib/constructed-response.js.map +0 -1
- package/lib/customizable.js +0 -42
- package/lib/customizable.js.map +0 -1
- package/lib/drag-in-the-blank.js +0 -363
- package/lib/drag-in-the-blank.js.map +0 -1
- package/lib/index.js +0 -55
- package/lib/index.js.map +0 -1
- package/lib/inline-dropdown.js +0 -40
- package/lib/inline-dropdown.js.map +0 -1
- package/lib/keyboard-coordinates.js +0 -156
- package/lib/keyboard-coordinates.js.map +0 -1
- package/lib/mask.js +0 -203
- package/lib/mask.js.map +0 -1
- package/lib/serialization.js +0 -261
- package/lib/serialization.js.map +0 -1
- package/lib/with-mask.js +0 -97
- package/lib/with-mask.js.map +0 -1
- package/src/__tests__/drag-in-the-blank.test.js +0 -256
- package/src/__tests__/index.test.js +0 -38
- package/src/__tests__/keyboard-coordinates.test.js +0 -202
- package/src/__tests__/mask.test.js +0 -479
- package/src/__tests__/serialization.test.js +0 -54
- package/src/__tests__/utils.js +0 -1
- package/src/__tests__/with-mask.test.js +0 -76
- package/src/choices/__tests__/index.test.js +0 -212
- package/src/choices/choice.jsx +0 -113
- package/src/choices/index.jsx +0 -88
- package/src/componentize.js +0 -13
- package/src/components/__tests__/blank.test.js +0 -413
- package/src/components/__tests__/correct-input.test.js +0 -90
- package/src/components/__tests__/dropdown.test.js +0 -129
- package/src/components/__tests__/input.test.js +0 -102
- package/src/components/blank.jsx +0 -504
- package/src/components/correct-input.jsx +0 -82
- package/src/components/dropdown.jsx +0 -421
- package/src/components/input.jsx +0 -48
- package/src/constructed-response.jsx +0 -87
- package/src/customizable.jsx +0 -34
- package/src/drag-in-the-blank.jsx +0 -351
- package/src/index.js +0 -16
- package/src/inline-dropdown.jsx +0 -29
- package/src/keyboard-coordinates.js +0 -147
- package/src/mask.jsx +0 -174
- package/src/serialization.js +0 -260
- package/src/with-mask.jsx +0 -75
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import componentize from '../componentize';
|
|
2
|
-
import { deserialize } from '../serialization';
|
|
3
|
-
|
|
4
|
-
describe('index', () => {
|
|
5
|
-
describe('componentize', () => {
|
|
6
|
-
it('should return an array with the appropriate markup', () => {
|
|
7
|
-
const dropDownMarkup = componentize('{{0}} foo {{1}}', 'dropdown');
|
|
8
|
-
|
|
9
|
-
expect(dropDownMarkup).toEqual({
|
|
10
|
-
markup:
|
|
11
|
-
'<span data-component="dropdown" data-id="0"></span> foo <span data-component="dropdown" data-id="1"></span>',
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('serialization', () => {
|
|
17
|
-
it('should have default node a span', () => {
|
|
18
|
-
expect(deserialize('something')).toEqual(
|
|
19
|
-
expect.objectContaining({
|
|
20
|
-
object: 'value',
|
|
21
|
-
document: {
|
|
22
|
-
object: 'document',
|
|
23
|
-
data: {},
|
|
24
|
-
nodes: [
|
|
25
|
-
{
|
|
26
|
-
object: 'block',
|
|
27
|
-
data: {},
|
|
28
|
-
isVoid: false,
|
|
29
|
-
type: 'span',
|
|
30
|
-
nodes: [{ object: 'text', leaves: [{ text: 'something' }] }],
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
}),
|
|
35
|
-
);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { KeyboardCode } from '@dnd-kit/core';
|
|
2
|
-
import { closestDroppableKeyboardCoordinates } from '../keyboard-coordinates';
|
|
3
|
-
|
|
4
|
-
function rectsToContext(rects) {
|
|
5
|
-
const droppableRects = new Map(Object.entries(rects));
|
|
6
|
-
const droppableContainers = new Map(Object.keys(rects).map((id) => [id, { disabled: false }]));
|
|
7
|
-
|
|
8
|
-
return { droppableRects, droppableContainers };
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function makeEvent(code, shiftKey = false) {
|
|
12
|
-
return { code, preventDefault: () => {}, shiftKey };
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Mirrors dnd-kit's own KeyboardSensor, which always derives collisionRect's top-left
|
|
16
|
-
// from the dragged item's current on-screen position on every keydown — so a test's
|
|
17
|
-
// collisionRect must track currentCoordinates the same way on every simulated press,
|
|
18
|
-
// not stay fixed while currentCoordinates changes across multiple presses.
|
|
19
|
-
function press(rects, currentCoordinates, itemSize, event, active) {
|
|
20
|
-
const context = {
|
|
21
|
-
...rectsToContext(rects),
|
|
22
|
-
collisionRect: { left: currentCoordinates.x, top: currentCoordinates.y, ...itemSize },
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
return closestDroppableKeyboardCoordinates(event, { active, context, currentCoordinates });
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
describe('closestDroppableKeyboardCoordinates', () => {
|
|
29
|
-
describe('arrow keys', () => {
|
|
30
|
-
it("nudges the dragged item by dnd-kit's own default step (25px), unchanged", () => {
|
|
31
|
-
const context = { ...rectsToContext({}), collisionRect: { left: 0, top: 0, width: 100, height: 40 } };
|
|
32
|
-
const currentCoordinates = { x: 10, y: 20 };
|
|
33
|
-
|
|
34
|
-
expect(
|
|
35
|
-
closestDroppableKeyboardCoordinates(makeEvent(KeyboardCode.Down), { context, currentCoordinates }),
|
|
36
|
-
).toEqual({ x: 10, y: 45 });
|
|
37
|
-
expect(
|
|
38
|
-
closestDroppableKeyboardCoordinates(makeEvent(KeyboardCode.Up), { context, currentCoordinates }),
|
|
39
|
-
).toEqual({ x: 10, y: -5 });
|
|
40
|
-
expect(
|
|
41
|
-
closestDroppableKeyboardCoordinates(makeEvent(KeyboardCode.Right), { context, currentCoordinates }),
|
|
42
|
-
).toEqual({ x: 35, y: 20 });
|
|
43
|
-
expect(
|
|
44
|
-
closestDroppableKeyboardCoordinates(makeEvent(KeyboardCode.Left), { context, currentCoordinates }),
|
|
45
|
-
).toEqual({ x: -15, y: 20 });
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
describe('Tab / Shift+Tab', () => {
|
|
50
|
-
const blank0Rect = { left: 0, top: 0, width: 120, height: 40, right: 120, bottom: 40 };
|
|
51
|
-
const blank1Rect = { left: 0, top: 60, width: 120, height: 40, right: 120, bottom: 100 };
|
|
52
|
-
const boardRect = { left: 0, top: 120, width: 400, height: 300, right: 400, bottom: 420 };
|
|
53
|
-
const baseRects = {
|
|
54
|
-
'mask-blank-drop-0': blank0Rect,
|
|
55
|
-
'mask-blank-drop-1': blank1Rect,
|
|
56
|
-
'drag-in-the-blank-droppable': boardRect,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
it('jumps to the next droppable in top-to-bottom order, landing at its center-left point', () => {
|
|
60
|
-
const currentCoordinates = { x: blank0Rect.left, y: blank0Rect.top };
|
|
61
|
-
|
|
62
|
-
const next = press(baseRects, currentCoordinates, { width: 120, height: 40 }, makeEvent('Tab'));
|
|
63
|
-
|
|
64
|
-
expect(next).toEqual({ x: blank1Rect.left, y: blank1Rect.top + blank1Rect.height / 2 });
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('cycles backwards with Shift+Tab, wrapping to the choice board', () => {
|
|
68
|
-
const currentCoordinates = { x: blank0Rect.left, y: blank0Rect.top };
|
|
69
|
-
|
|
70
|
-
const next = press(baseRects, currentCoordinates, { width: 120, height: 40 }, makeEvent('Tab', true));
|
|
71
|
-
|
|
72
|
-
expect(next).toEqual({ x: boardRect.left, y: boardRect.top + boardRect.height / 2 });
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("excludes a dragged blank's own drop-zone from the cycle", () => {
|
|
76
|
-
// A blank is simultaneously draggable and droppable for its own slot (the same
|
|
77
|
-
// shape as match-list's placed "target" tiles). Without excluding it, containment
|
|
78
|
-
// would match the blank to itself and cycle relative to itself instead of its
|
|
79
|
-
// real neighbors — this test is constructed so the two behaviors give different,
|
|
80
|
-
// distinguishable results (not just coincidentally the same answer).
|
|
81
|
-
const blankARect = { left: 0, top: 0, width: 120, height: 40, right: 120, bottom: 40 };
|
|
82
|
-
const blankBRect = { left: 0, top: 60, width: 120, height: 40, right: 120, bottom: 100 };
|
|
83
|
-
const blankCRect = { left: 0, top: 120, width: 120, height: 40, right: 120, bottom: 160 };
|
|
84
|
-
const rects = {
|
|
85
|
-
'mask-blank-drop-a': blankARect,
|
|
86
|
-
'mask-blank-drop-b': blankBRect,
|
|
87
|
-
'mask-blank-drop-c': blankCRect,
|
|
88
|
-
};
|
|
89
|
-
const active = { data: { current: { id: 'b', fromChoice: false, type: 'MaskBlank' } } };
|
|
90
|
-
// Sitting exactly at blank B's own position.
|
|
91
|
-
const currentCoordinates = { x: blankBRect.left, y: blankBRect.top };
|
|
92
|
-
|
|
93
|
-
const next = press(rects, currentCoordinates, { width: 120, height: 40 }, makeEvent('Tab', true), active);
|
|
94
|
-
|
|
95
|
-
// With B's own slot excluded, Shift+Tab from B's position falls back to
|
|
96
|
-
// nearest-by-dropPosition among the remaining targets (A and C) — A is closer to
|
|
97
|
-
// B's actual position, making A the resolved "current", so reverse from there
|
|
98
|
-
// lands on C. Without the exclusion, containment would match B to itself
|
|
99
|
-
// directly (index 1 of [A, B, C] sorted by position), landing on A instead.
|
|
100
|
-
expect(next).toEqual({ x: blankCRect.left, y: blankCRect.top + blankCRect.height / 2 });
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('keeps advancing on repeated Shift+Tab when the choice board is much wider than the dragged item', () => {
|
|
104
|
-
// Regression case for the bug already found and fixed in match-list/image-cloze-
|
|
105
|
-
// association: matching the "current" target by reconstructing a center from the
|
|
106
|
-
// dragged item's own small size (instead of checking which target's rect actually
|
|
107
|
-
// contains it) makes the *next* press re-match a completely different droppable
|
|
108
|
-
// once the item is actually sitting on a wide target, so it looks like the press
|
|
109
|
-
// does nothing.
|
|
110
|
-
const wideBlankRect = { left: 0, top: 0, width: 900, height: 40, right: 900, bottom: 40 };
|
|
111
|
-
const rects = { 'mask-blank-drop-0': wideBlankRect, 'drag-in-the-blank-droppable': boardRect };
|
|
112
|
-
const itemSize = { width: 100, height: 40 };
|
|
113
|
-
|
|
114
|
-
const afterFirst = press(rects, { x: boardRect.left, y: boardRect.top }, itemSize, makeEvent('Tab', true));
|
|
115
|
-
|
|
116
|
-
expect(afterFirst).toEqual({ x: 0, y: 20 }); // wide blank's center-left point
|
|
117
|
-
|
|
118
|
-
const afterSecond = press(rects, afterFirst, itemSize, makeEvent('Tab', true));
|
|
119
|
-
|
|
120
|
-
expect(afterSecond).toEqual({ x: boardRect.left, y: boardRect.top + boardRect.height / 2 });
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('correctly identifies the choice board as the current target when picking up an item positioned near its edge, close to a small neighboring blank', () => {
|
|
124
|
-
// Regression case for the OTHER failure mode: matching "current target" purely by
|
|
125
|
-
// nearest-dropPosition (instead of containment first) can misidentify a large
|
|
126
|
-
// droppable as some small, unrelated nearby one, because a large droppable's
|
|
127
|
-
// dropPosition is anchored at its own vertical middle.
|
|
128
|
-
const tallBoardRect = { left: 0, top: 0, width: 400, height: 600, right: 400, bottom: 600 };
|
|
129
|
-
const smallBlankRect = { left: 0, top: -60, width: 100, height: 40, right: 100, bottom: -20 };
|
|
130
|
-
const rects = { 'mask-blank-drop-0': smallBlankRect, 'drag-in-the-blank-droppable': tallBoardRect };
|
|
131
|
-
const itemSize = { width: 100, height: 40 };
|
|
132
|
-
|
|
133
|
-
const currentCoordinates = { x: 0, y: 10 };
|
|
134
|
-
|
|
135
|
-
const next = press(rects, currentCoordinates, itemSize, makeEvent('Tab'));
|
|
136
|
-
|
|
137
|
-
expect(next).toEqual({ x: smallBlankRect.left, y: smallBlankRect.top + smallBlankRect.height / 2 });
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('keeps the choice board as a fixed last stop instead of sorting it in by its own center, when the board spans multiple blank rows', () => {
|
|
141
|
-
// Regression case for a real bug found via manual browser testing: with 3
|
|
142
|
-
// choices stacked beside wrapped inline text (`choicePosition: 'right'`), the
|
|
143
|
-
// tall choice board's own center fell numerically BETWEEN blank 2 and blank 3's
|
|
144
|
-
// rows. Sorting it by position the same way as a blank interleaved it into the
|
|
145
|
-
// middle of the cycle, so the very first Tab press after picking up a pool
|
|
146
|
-
// choice jumped straight to blank 3, skipping blanks 1 and 2 entirely.
|
|
147
|
-
const blank0Rect = { left: 0, top: 200, width: 50, height: 50, right: 50, bottom: 250 };
|
|
148
|
-
const blank1Rect = { left: 0, top: 250, width: 50, height: 50, right: 50, bottom: 300 };
|
|
149
|
-
const blank2Rect = { left: 0, top: 285, width: 50, height: 50, right: 50, bottom: 335 };
|
|
150
|
-
// Spans all three choices stacked beside the text — its center (287.5) falls
|
|
151
|
-
// between blank1's (275) and blank2's (310), more than 10px from either, so the
|
|
152
|
-
// old position-based sort placed it between them.
|
|
153
|
-
const tallBoardRect = { left: 400, top: 195, width: 80, height: 185, right: 480, bottom: 380 };
|
|
154
|
-
const rects = {
|
|
155
|
-
'mask-blank-drop-0': blank0Rect,
|
|
156
|
-
'mask-blank-drop-1': blank1Rect,
|
|
157
|
-
'mask-blank-drop-2': blank2Rect,
|
|
158
|
-
'drag-in-the-blank-droppable': tallBoardRect,
|
|
159
|
-
};
|
|
160
|
-
const active = { data: { current: { fromChoice: true, choice: { id: 'x' }, type: 'MaskBlank' } } };
|
|
161
|
-
const itemSize = { width: 48, height: 50 };
|
|
162
|
-
// Picking up a choice from within the board — its own current position, before
|
|
163
|
-
// any movement, sits inside the board's rect.
|
|
164
|
-
const currentCoordinates = { x: 415, y: 205 };
|
|
165
|
-
|
|
166
|
-
const next = press(rects, currentCoordinates, itemSize, makeEvent('Tab'), active);
|
|
167
|
-
|
|
168
|
-
expect(next).toEqual({ x: blank0Rect.left, y: blank0Rect.top + blank0Rect.height / 2 });
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('cycles through every blank in position order, then the board, then wraps — even when the board would otherwise sort into the middle', () => {
|
|
172
|
-
const blank0Rect = { left: 0, top: 200, width: 50, height: 50, right: 50, bottom: 250 };
|
|
173
|
-
const blank1Rect = { left: 0, top: 250, width: 50, height: 50, right: 50, bottom: 300 };
|
|
174
|
-
const blank2Rect = { left: 0, top: 285, width: 50, height: 50, right: 50, bottom: 335 };
|
|
175
|
-
const tallBoardRect = { left: 400, top: 195, width: 80, height: 185, right: 480, bottom: 380 };
|
|
176
|
-
const rects = {
|
|
177
|
-
'mask-blank-drop-0': blank0Rect,
|
|
178
|
-
'mask-blank-drop-1': blank1Rect,
|
|
179
|
-
'mask-blank-drop-2': blank2Rect,
|
|
180
|
-
'drag-in-the-blank-droppable': tallBoardRect,
|
|
181
|
-
};
|
|
182
|
-
const active = { data: { current: { fromChoice: true, choice: { id: 'x' }, type: 'MaskBlank' } } };
|
|
183
|
-
const itemSize = { width: 48, height: 50 };
|
|
184
|
-
|
|
185
|
-
let coords = { x: 415, y: 205 };
|
|
186
|
-
const visited = [];
|
|
187
|
-
|
|
188
|
-
for (let i = 0; i < 5; i++) {
|
|
189
|
-
coords = press(rects, coords, itemSize, makeEvent('Tab'), active);
|
|
190
|
-
visited.push(coords);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
expect(visited).toEqual([
|
|
194
|
-
{ x: blank0Rect.left, y: blank0Rect.top + blank0Rect.height / 2 },
|
|
195
|
-
{ x: blank1Rect.left, y: blank1Rect.top + blank1Rect.height / 2 },
|
|
196
|
-
{ x: blank2Rect.left, y: blank2Rect.top + blank2Rect.height / 2 },
|
|
197
|
-
{ x: tallBoardRect.left, y: tallBoardRect.top + tallBoardRect.height / 2 },
|
|
198
|
-
{ x: blank0Rect.left, y: blank0Rect.top + blank0Rect.height / 2 }, // wraps
|
|
199
|
-
]);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
});
|