@mborecki/crossword 0.0.2 → 0.2.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/cjs/{index-TyGpRn4d.js → index-BlTGwvVC.js} +63 -2
- package/dist/cjs/{index-CwHIXXW5.js → index-CEGyCfpa.js} +29 -1
- package/dist/cjs/index.cjs.js +2 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/mb-crossword.cjs.entry.js +159 -38
- package/dist/cjs/mb-crossword.cjs.js +2 -2
- package/dist/collection/components/crossword/cell.js +7 -2
- package/dist/collection/components/crossword/clue.js +2 -2
- package/dist/collection/components/crossword/mb-crossword.css +107 -13
- package/dist/collection/components/crossword/mb-crossword.js +189 -32
- package/dist/collection/utils/utils.js +6 -0
- package/dist/components/index.js +1 -1
- package/dist/components/mb-crossword.js +1 -1
- package/dist/esm/{index-B4XIBYtu.js → index-BGHKtxML.js} +63 -2
- package/dist/esm/{index-0i8AYf_G.js → index-Dn3GSx6U.js} +29 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/mb-crossword.entry.js +159 -38
- package/dist/esm/mb-crossword.js +3 -3
- package/dist/mb-crossword/index.esm.js +1 -1
- package/dist/mb-crossword/mb-crossword.esm.js +1 -1
- package/dist/mb-crossword/p-34ea8cf1.entry.js +1 -0
- package/dist/mb-crossword/{p-B4XIBYtu.js → p-BGHKtxML.js} +2 -2
- package/dist/mb-crossword/p-Dn3GSx6U.js +1 -0
- package/dist/types/components/crossword/cell.d.ts +3 -1
- package/dist/types/components/crossword/clue.d.ts +5 -3
- package/dist/types/components/crossword/mb-crossword.d.ts +18 -6
- package/dist/types/components/crossword/types.d.ts +21 -2
- package/dist/types/components.d.ts +9 -0
- package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/grid/src/grid.d.ts +12 -0
- package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/grid/vitest.config.d.ts +2 -0
- package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/vec2/src/vec2.d.ts +9 -2
- package/dist/types/utils/utils.d.ts +1 -0
- package/package.json +6 -1
- package/dist/mb-crossword/p-0i8AYf_G.js +0 -1
- package/dist/mb-crossword/p-5b227b8e.entry.js +0 -1
|
@@ -1,44 +1,86 @@
|
|
|
1
1
|
*[part=main] {
|
|
2
|
+
position: relative;
|
|
2
3
|
display: grid;
|
|
3
|
-
grid-template-areas: "
|
|
4
|
-
grid-template-columns: 1fr
|
|
4
|
+
grid-template-areas: "board" "clues";
|
|
5
|
+
grid-template-columns: 1fr;
|
|
6
|
+
}
|
|
7
|
+
@media (min-width: 768px) {
|
|
8
|
+
*[part=main] {
|
|
9
|
+
grid-template-areas: "clues board" "clues .";
|
|
10
|
+
grid-template-columns: 1fr 1fr;
|
|
11
|
+
}
|
|
5
12
|
}
|
|
6
13
|
*[part=main].--focused {
|
|
7
14
|
background: lightgrey;
|
|
8
15
|
}
|
|
16
|
+
*[part=main] input.dummy {
|
|
17
|
+
pointer-events: none;
|
|
18
|
+
opacity: 0.2;
|
|
19
|
+
z-index: 100;
|
|
20
|
+
grid-area: board;
|
|
21
|
+
border: none;
|
|
22
|
+
}
|
|
9
23
|
|
|
10
24
|
[part=clues] {
|
|
11
25
|
grid-area: clues;
|
|
12
26
|
display: grid;
|
|
13
27
|
grid-template-columns: 1fr 1fr;
|
|
28
|
+
gap: 16px;
|
|
29
|
+
}
|
|
30
|
+
[part=clues].oneList {
|
|
31
|
+
grid-template-columns: 1fr;
|
|
14
32
|
}
|
|
15
33
|
|
|
16
34
|
[part=clue].--current {
|
|
17
|
-
background: lightcyan;
|
|
35
|
+
background: var(--clue-current-background, lightcyan);
|
|
36
|
+
position: sticky;
|
|
37
|
+
bottom: 0;
|
|
38
|
+
left: 0;
|
|
39
|
+
right: 0;
|
|
40
|
+
}
|
|
41
|
+
[part=clue] .preview {
|
|
42
|
+
font-weight: bold;
|
|
43
|
+
letter-spacing: 0.2em;
|
|
44
|
+
text-align: center;
|
|
45
|
+
display: block;
|
|
46
|
+
text-transform: uppercase;
|
|
18
47
|
}
|
|
19
48
|
|
|
20
49
|
[part=board] {
|
|
21
50
|
grid-area: board;
|
|
22
|
-
display:
|
|
51
|
+
display: block;
|
|
52
|
+
position: relative;
|
|
53
|
+
container-type: size;
|
|
54
|
+
background: var(--board-background, darkgoldenrod);
|
|
55
|
+
--cell-border-width: 2px;
|
|
56
|
+
--cell-width-temp: calc((100cqw - var(--cell-border-width)) / var(--board-width, 10));
|
|
57
|
+
--cell-width: var(--cell-width-temp);
|
|
58
|
+
--cell-width: round(var(--cell-width-temp), 1px);
|
|
23
59
|
}
|
|
24
60
|
|
|
25
61
|
[part=cell] {
|
|
62
|
+
display: block;
|
|
63
|
+
color: var(--cell-color, #11138d);
|
|
64
|
+
width: calc(var(--cell-width) - var(--cell-border-width));
|
|
26
65
|
aspect-ratio: 1;
|
|
27
|
-
background: #d9d9d9;
|
|
28
|
-
position:
|
|
66
|
+
background: var(--cell-background, #d9d9d9);
|
|
67
|
+
position: absolute;
|
|
29
68
|
container-type: size;
|
|
69
|
+
top: calc(var(--y, 0) * var(--cell-width));
|
|
70
|
+
left: calc(var(--x, 0) * var(--cell-width));
|
|
71
|
+
border: var(--cell-border-width) solid var(--cell-border-color, red);
|
|
30
72
|
}
|
|
31
|
-
[part=cell]
|
|
32
|
-
background: #999;
|
|
33
|
-
}
|
|
34
|
-
[part=cell].--blocked {
|
|
35
|
-
background: black;
|
|
73
|
+
[part=cell].--alt {
|
|
74
|
+
background: var(--cell-background-alt, #999);
|
|
36
75
|
}
|
|
37
76
|
[part=cell].--in-current-clue {
|
|
38
|
-
box-shadow: inset 0 0 2px 2px lightblue;
|
|
77
|
+
box-shadow: inset 0 0 2px 2px var(--cell-selected-background, lightblue);
|
|
39
78
|
}
|
|
40
79
|
[part=cell].--selected {
|
|
41
|
-
background: lightblue;
|
|
80
|
+
background: var(--cell-selected-background, lightblue);
|
|
81
|
+
}
|
|
82
|
+
[part=cell].--special {
|
|
83
|
+
background: var(--cell-special-background, lightgreen);
|
|
42
84
|
}
|
|
43
85
|
[part=cell] ._inner {
|
|
44
86
|
position: absolute;
|
|
@@ -54,4 +96,56 @@
|
|
|
54
96
|
|
|
55
97
|
[part=preview] {
|
|
56
98
|
display: none;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
[part=special-border] {
|
|
102
|
+
display: block;
|
|
103
|
+
background: black;
|
|
104
|
+
position: absolute;
|
|
105
|
+
z-index: 100;
|
|
106
|
+
--s-border: max(2px, var(--cell-border-width));
|
|
107
|
+
}
|
|
108
|
+
[part=special-border].left, [part=special-border].right {
|
|
109
|
+
width: var(--s-border);
|
|
110
|
+
height: calc(var(--cell-width) - var(--cell-border-width));
|
|
111
|
+
top: calc(var(--y, 0) * var(--cell-width) + var(--cell-border-width));
|
|
112
|
+
}
|
|
113
|
+
[part=special-border].left {
|
|
114
|
+
left: calc(var(--x, 0) * var(--cell-width) - var(--s-border) / 2);
|
|
115
|
+
}
|
|
116
|
+
[part=special-border].right {
|
|
117
|
+
left: calc((var(--x, 0) + 1) * var(--cell-width) - var(--s-border) / 2);
|
|
118
|
+
}
|
|
119
|
+
[part=special-border].top, [part=special-border].bottom {
|
|
120
|
+
width: calc(var(--cell-width) - var(--cell-border-width));
|
|
121
|
+
height: var(--s-border);
|
|
122
|
+
left: calc(var(--x, 0) * var(--cell-width) + var(--cell-border-width));
|
|
123
|
+
}
|
|
124
|
+
[part=special-border].top {
|
|
125
|
+
top: calc(var(--y, 0) * var(--cell-width));
|
|
126
|
+
}
|
|
127
|
+
[part=special-border].bottom {
|
|
128
|
+
top: calc((var(--y, 0) + 1) * var(--cell-width));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
[part=label] {
|
|
132
|
+
display: grid;
|
|
133
|
+
place-content: center;
|
|
134
|
+
position: absolute;
|
|
135
|
+
container-type: size;
|
|
136
|
+
top: calc(var(--y, 0) * var(--cell-width));
|
|
137
|
+
left: calc(var(--x, 0) * var(--cell-width));
|
|
138
|
+
width: calc(var(--cell-width) - var(--cell-border-width));
|
|
139
|
+
aspect-ratio: 1;
|
|
140
|
+
}
|
|
141
|
+
[part=label] ._inner {
|
|
142
|
+
position: absolute;
|
|
143
|
+
top: 0;
|
|
144
|
+
left: 0;
|
|
145
|
+
right: 0;
|
|
146
|
+
bottom: 0;
|
|
147
|
+
display: grid;
|
|
148
|
+
place-content: center;
|
|
149
|
+
text-transform: uppercase;
|
|
150
|
+
font-size: 60cqh;
|
|
57
151
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { forceUpdate, h } from "@stencil/core";
|
|
2
2
|
import { Clue } from "./clue";
|
|
3
3
|
import { Cell } from "./cell";
|
|
4
|
-
import { indexFromXY,
|
|
4
|
+
import { indexFromXY, isInputEventLetter, Vec2fromIndex } from "../../utils/utils";
|
|
5
5
|
import { Vec2 } from "@mb-puzzle/vec2";
|
|
6
6
|
export class MBCrossword {
|
|
7
7
|
init = true;
|
|
8
8
|
data;
|
|
9
|
+
showCluePreview = true;
|
|
10
|
+
textInput;
|
|
9
11
|
hWords = [];
|
|
10
12
|
vWords = [];
|
|
11
13
|
currentClueId = null;
|
|
@@ -13,6 +15,12 @@ export class MBCrossword {
|
|
|
13
15
|
isFocused = false;
|
|
14
16
|
selectedCell = null;
|
|
15
17
|
componentWillLoad() {
|
|
18
|
+
console.log('componentWillLoad', this.init, this.data);
|
|
19
|
+
if (this.init && this.data) {
|
|
20
|
+
this.initGame();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
watchData() {
|
|
16
24
|
if (this.init && this.data) {
|
|
17
25
|
this.initGame();
|
|
18
26
|
}
|
|
@@ -24,6 +32,7 @@ export class MBCrossword {
|
|
|
24
32
|
];
|
|
25
33
|
}
|
|
26
34
|
async initGame(data = this.data) {
|
|
35
|
+
console.log('initGame');
|
|
27
36
|
if (!data.words) {
|
|
28
37
|
throw new Error('Words definition missing');
|
|
29
38
|
}
|
|
@@ -41,8 +50,22 @@ export class MBCrossword {
|
|
|
41
50
|
this.vWords = [...this.vWords, w];
|
|
42
51
|
}
|
|
43
52
|
});
|
|
53
|
+
this.specialBorders = data.specialBorders ?? [];
|
|
54
|
+
this.specialCells = data.specialCells ?? [];
|
|
55
|
+
this.labels = data.labels ?? [];
|
|
44
56
|
this.buildBoard();
|
|
45
57
|
}
|
|
58
|
+
async checkAnswer() {
|
|
59
|
+
const cells = this.cells.filter(c => !c.isBlocked);
|
|
60
|
+
console.log(cells);
|
|
61
|
+
cells.forEach(c => {
|
|
62
|
+
console.log(`${c.value} === ${c.answer}`, `${c.x},${c.y}`, c.value === c.answer);
|
|
63
|
+
});
|
|
64
|
+
return cells.every(c => c.value === c.answer);
|
|
65
|
+
}
|
|
66
|
+
specialBorders = [];
|
|
67
|
+
specialCells = [];
|
|
68
|
+
labels = [];
|
|
46
69
|
boardWidth = 0;
|
|
47
70
|
boardHeight = 0;
|
|
48
71
|
cells = [];
|
|
@@ -77,6 +100,7 @@ export class MBCrossword {
|
|
|
77
100
|
const v = Vec2.from(w);
|
|
78
101
|
const cellIndex = indexFromXY(new Vec2(v.x + i, v.y), boardWidth);
|
|
79
102
|
cells[cellIndex].isBlocked = false;
|
|
103
|
+
cells[cellIndex].answer = w.word[i];
|
|
80
104
|
}
|
|
81
105
|
}
|
|
82
106
|
if (w.orientation === 'vertical') {
|
|
@@ -84,6 +108,7 @@ export class MBCrossword {
|
|
|
84
108
|
const v = Vec2.from(w);
|
|
85
109
|
const cellIndex = indexFromXY(new Vec2(v.x, v.y + i), boardWidth);
|
|
86
110
|
cells[cellIndex].isBlocked = false;
|
|
111
|
+
cells[cellIndex].answer = w.word[i];
|
|
87
112
|
}
|
|
88
113
|
}
|
|
89
114
|
});
|
|
@@ -91,6 +116,9 @@ export class MBCrossword {
|
|
|
91
116
|
this.boardWidth = boardWidth;
|
|
92
117
|
this.boardHeight = boardHeight;
|
|
93
118
|
}
|
|
119
|
+
getClueById(id) {
|
|
120
|
+
return this.allWords.find(c => c.id === id) ?? null;
|
|
121
|
+
}
|
|
94
122
|
isInClue(xy, clue = this.currentClue) {
|
|
95
123
|
if (clue === null)
|
|
96
124
|
return false;
|
|
@@ -147,25 +175,58 @@ export class MBCrossword {
|
|
|
147
175
|
this.selectNextCell();
|
|
148
176
|
forceUpdate(this);
|
|
149
177
|
}
|
|
178
|
+
backspace() {
|
|
179
|
+
if (!this.selectedCell)
|
|
180
|
+
return;
|
|
181
|
+
if (this.selectedCell.value) {
|
|
182
|
+
this.selectedCell.value = '';
|
|
183
|
+
this.selectPrevCell();
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
this.selectPrevCell();
|
|
187
|
+
this.selectedCell.value = '';
|
|
188
|
+
}
|
|
189
|
+
forceUpdate(this);
|
|
190
|
+
}
|
|
150
191
|
selectNextCell() {
|
|
151
192
|
if (!this.selectedCell || !this.currentClue)
|
|
152
193
|
return;
|
|
153
194
|
const currentOrientation = this.currentClue.orientation;
|
|
154
|
-
if (
|
|
195
|
+
if (isLastCellInClue(this.currentClue, this.selectedCell)) {
|
|
155
196
|
const nextClueId = this.getNextClueId();
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
this.selectClue(this.hWords[0]?.id ?? this.vWords[0]?.id);
|
|
197
|
+
const clue = this.getClueById(nextClueId);
|
|
198
|
+
if (clue) {
|
|
199
|
+
this.selectClueByXY(Vec2.from(clue));
|
|
200
|
+
return;
|
|
161
201
|
}
|
|
162
202
|
return;
|
|
163
203
|
}
|
|
164
204
|
if (currentOrientation === 'horizontal') {
|
|
165
|
-
this.
|
|
205
|
+
this.selectClueByXY(new Vec2(this.selectedCell.x + 1, this.selectedCell.y));
|
|
166
206
|
}
|
|
167
207
|
if (currentOrientation === 'vertical') {
|
|
168
|
-
this.
|
|
208
|
+
this.selectClueByXY(new Vec2(this.selectedCell.x, this.selectedCell.y + 1));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
selectPrevCell() {
|
|
212
|
+
if (!this.selectedCell || !this.currentClue)
|
|
213
|
+
return;
|
|
214
|
+
const currentOrientation = this.currentClue.orientation;
|
|
215
|
+
if (isFirstCellInWord(this.currentClue, this.selectedCell)) {
|
|
216
|
+
const prevClueId = this.getPrevClueId();
|
|
217
|
+
const clue = this.getClueById(prevClueId);
|
|
218
|
+
if (clue) {
|
|
219
|
+
const cell = getClueLastCell(clue);
|
|
220
|
+
console.log(cell);
|
|
221
|
+
this.selectClueByXY(cell);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (currentOrientation === 'horizontal') {
|
|
226
|
+
this.selectClueByXY(new Vec2(this.selectedCell.x - 1, this.selectedCell.y));
|
|
227
|
+
}
|
|
228
|
+
if (currentOrientation === 'vertical') {
|
|
229
|
+
this.selectClueByXY(new Vec2(this.selectedCell.x, this.selectedCell.y - 1));
|
|
169
230
|
}
|
|
170
231
|
}
|
|
171
232
|
onFocusin() {
|
|
@@ -173,6 +234,7 @@ export class MBCrossword {
|
|
|
173
234
|
if (!this.currentClueId) {
|
|
174
235
|
this.currentClueId = this.allWords[0]?.id ?? null;
|
|
175
236
|
}
|
|
237
|
+
this.textInput.focus();
|
|
176
238
|
}
|
|
177
239
|
onFocusOut() {
|
|
178
240
|
this.isFocused = false;
|
|
@@ -236,8 +298,27 @@ export class MBCrossword {
|
|
|
236
298
|
if (!clues.length) {
|
|
237
299
|
return;
|
|
238
300
|
}
|
|
239
|
-
|
|
240
|
-
|
|
301
|
+
if (this.selectedCell && clues.length === 2 && v.eq(Vec2.from(this.selectedCell))) {
|
|
302
|
+
const betterClue = clues.find(c => c.orientation !== this.currentClue?.orientation);
|
|
303
|
+
this.selectClue(betterClue?.id ?? clues[0].id, { row: v.y, col: v.x });
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const betterClue = clues.find(c => c.orientation === this.currentClue?.orientation);
|
|
307
|
+
this.selectClue(betterClue?.id ?? clues[0].id, { row: v.y, col: v.x });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
getCluePreview(clue) {
|
|
311
|
+
if (!clue)
|
|
312
|
+
return '_';
|
|
313
|
+
const letters = Array(clue.word.length).fill('_');
|
|
314
|
+
for (let i = 0; i < clue.word.length; i++) {
|
|
315
|
+
const pointer = new Vec2(clue.x, clue.y).add(clue.orientation === 'vertical' ? new Vec2(0, 1 * i) : new Vec2(1 * i, 0));
|
|
316
|
+
const cell = this.cells[indexFromXY(pointer, this.boardWidth)];
|
|
317
|
+
if (cell.value) {
|
|
318
|
+
letters[i] = cell.value;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return letters.join('');
|
|
241
322
|
}
|
|
242
323
|
onKeyPress(event) {
|
|
243
324
|
console.log(event);
|
|
@@ -248,9 +329,6 @@ export class MBCrossword {
|
|
|
248
329
|
this.selectClue(nextClue);
|
|
249
330
|
}
|
|
250
331
|
}
|
|
251
|
-
if (isKeyboardEventLetter(event)) {
|
|
252
|
-
this.inputLetter(event.key.toLowerCase()[0]);
|
|
253
|
-
}
|
|
254
332
|
if (this.selectedCell) {
|
|
255
333
|
switch (event.key) {
|
|
256
334
|
case 'ArrowLeft':
|
|
@@ -269,29 +347,61 @@ export class MBCrossword {
|
|
|
269
347
|
this.selectClueByXY(this.findNonblockedCell(new Vec2(this.selectedCell.x, this.selectedCell.y), new Vec2(0, 1)));
|
|
270
348
|
event.preventDefault();
|
|
271
349
|
return;
|
|
350
|
+
case 'Backspace':
|
|
351
|
+
console.log('BACKSPACE!');
|
|
352
|
+
this.backspace();
|
|
272
353
|
}
|
|
273
354
|
}
|
|
274
355
|
}
|
|
356
|
+
onInput(event) {
|
|
357
|
+
if (isInputEventLetter(event)) {
|
|
358
|
+
this.inputLetter(event.data.toLowerCase()[0]);
|
|
359
|
+
}
|
|
360
|
+
this.textInput.value = '';
|
|
361
|
+
}
|
|
275
362
|
render() {
|
|
276
|
-
|
|
363
|
+
const hasVWords = Boolean(this.vWords.length);
|
|
364
|
+
const hasHWords = Boolean(this.hWords.length);
|
|
365
|
+
const twoLists = hasHWords && hasVWords;
|
|
366
|
+
return h("div", { key: '87d88806305c6102eeb76c3984d4b9c2ad2d9759', part: "main", class: {
|
|
277
367
|
"--focused": this.isFocused
|
|
278
|
-
}, onFocusin: this.onFocusin.bind(this), onFocusout: this.onFocusOut.bind(this)
|
|
368
|
+
}, onFocusin: this.onFocusin.bind(this), onFocusout: this.onFocusOut.bind(this) }, h("input", { key: '49cdb053a4d2c4ad2c7eb881488b18c68e31fe65', type: "text", class: "dummy", ref: (el) => this.textInput = el, onKeyDown: this.onKeyPress.bind(this), onInput: this.onInput.bind(this) }), h("div", { key: '0ca71a907f70e17a6d2d10bff9462bd0b2284007', part: "clues", class: {
|
|
369
|
+
twoLists, oneList: !twoLists
|
|
370
|
+
} }, hasHWords ? h("div", { part: "clue-list" }, this.hWords.map(w => {
|
|
279
371
|
const isCurrent = w.id === this.currentClueId;
|
|
280
|
-
return h(Clue, { word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
|
|
281
|
-
})), h("div", {
|
|
372
|
+
return h(Clue, { showPreview: this.showCluePreview, preview: this.getCluePreview(w), word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
|
|
373
|
+
})) : '', hasVWords ? h("div", { part: "clue-list" }, this.vWords.map(w => {
|
|
282
374
|
const isCurrent = w.id === this.currentClueId;
|
|
283
|
-
return h(Clue, { word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
|
|
284
|
-
}))), h("div", { key: '
|
|
285
|
-
'--
|
|
286
|
-
'grid-template-columns': `repeat(${this.boardWidth}, 1fr)
|
|
287
|
-
|
|
375
|
+
return h(Clue, { showPreview: this.showCluePreview, preview: this.getCluePreview(w), word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
|
|
376
|
+
})) : ''), h("div", { key: 'ea16dca25fe7884d25f9748f98740ad83e25293e', part: "board", style: {
|
|
377
|
+
'--board-width': `${this.boardWidth}`,
|
|
378
|
+
'grid-template-columns': `repeat(${this.boardWidth}, 1fr)`,
|
|
379
|
+
aspectRatio: `${this.boardWidth / this.boardHeight}`
|
|
380
|
+
} }, this.cells.filter(c => !c.isBlocked).map(cell => {
|
|
288
381
|
const isInCurrentClue = this.isInClue(cell);
|
|
289
382
|
const isSelected = this.isSelectedCell(cell);
|
|
290
|
-
|
|
291
|
-
|
|
383
|
+
const isSpecial = this.specialCells.some(c => c.x === cell.x && c.y === cell.y);
|
|
384
|
+
return h(Cell, { isSpecial: isSpecial, onPointerDown: () => this.selectClueByXY(Vec2.from(cell)), isInCurrentClue: isInCurrentClue, isSelected: isSelected, data: cell });
|
|
385
|
+
}), this.specialBorders.map((b, index) => {
|
|
386
|
+
return h("div", { key: index, part: "special-border", class: {
|
|
387
|
+
'top': Boolean(b.border & 0x1000),
|
|
388
|
+
'right': Boolean(b.border & 0x0100),
|
|
389
|
+
'bottom': Boolean(b.border & 0x0010),
|
|
390
|
+
'left': Boolean(b.border & 0x0001),
|
|
391
|
+
}, style: {
|
|
392
|
+
"--x": `${b.x}`,
|
|
393
|
+
"--y": `${b.y}`
|
|
394
|
+
} });
|
|
395
|
+
}), this.labels.map((label) => {
|
|
396
|
+
return h("div", { part: "label", style: {
|
|
397
|
+
"--x": `${label.x}`,
|
|
398
|
+
"--y": `${label.y}`
|
|
399
|
+
}, onPointerDown: () => this.selectClue(label.clueId) }, h("div", { class: "_inner" }, label.text));
|
|
400
|
+
})), h("div", { key: 'd391413e7be3dee148f2f5e6d8fbf22742278a0c', part: "preview" }, "Tu bedzie podgl\u0105d: ", this.currentClueId));
|
|
292
401
|
}
|
|
293
402
|
static get is() { return "mb-crossword"; }
|
|
294
403
|
static get encapsulation() { return "shadow"; }
|
|
404
|
+
static get delegatesFocus() { return true; }
|
|
295
405
|
static get originalStyleUrls() {
|
|
296
406
|
return {
|
|
297
407
|
"$": ["mb-crossword.scss"]
|
|
@@ -347,6 +457,26 @@ export class MBCrossword {
|
|
|
347
457
|
},
|
|
348
458
|
"getter": false,
|
|
349
459
|
"setter": false
|
|
460
|
+
},
|
|
461
|
+
"showCluePreview": {
|
|
462
|
+
"type": "boolean",
|
|
463
|
+
"mutable": false,
|
|
464
|
+
"complexType": {
|
|
465
|
+
"original": "boolean",
|
|
466
|
+
"resolved": "boolean",
|
|
467
|
+
"references": {}
|
|
468
|
+
},
|
|
469
|
+
"required": false,
|
|
470
|
+
"optional": false,
|
|
471
|
+
"docs": {
|
|
472
|
+
"tags": [],
|
|
473
|
+
"text": ""
|
|
474
|
+
},
|
|
475
|
+
"getter": false,
|
|
476
|
+
"setter": false,
|
|
477
|
+
"reflect": false,
|
|
478
|
+
"attribute": "show-clue-preview",
|
|
479
|
+
"defaultValue": "true"
|
|
350
480
|
}
|
|
351
481
|
};
|
|
352
482
|
}
|
|
@@ -358,6 +488,9 @@ export class MBCrossword {
|
|
|
358
488
|
"currentClue": {},
|
|
359
489
|
"isFocused": {},
|
|
360
490
|
"selectedCell": {},
|
|
491
|
+
"specialBorders": {},
|
|
492
|
+
"specialCells": {},
|
|
493
|
+
"labels": {},
|
|
361
494
|
"boardWidth": {},
|
|
362
495
|
"boardHeight": {},
|
|
363
496
|
"cells": {}
|
|
@@ -391,15 +524,39 @@ export class MBCrossword {
|
|
|
391
524
|
"text": "",
|
|
392
525
|
"tags": []
|
|
393
526
|
}
|
|
527
|
+
},
|
|
528
|
+
"checkAnswer": {
|
|
529
|
+
"complexType": {
|
|
530
|
+
"signature": "() => Promise<boolean>",
|
|
531
|
+
"parameters": [],
|
|
532
|
+
"references": {
|
|
533
|
+
"Promise": {
|
|
534
|
+
"location": "global",
|
|
535
|
+
"id": "global::Promise"
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
"return": "Promise<boolean>"
|
|
539
|
+
},
|
|
540
|
+
"docs": {
|
|
541
|
+
"text": "",
|
|
542
|
+
"tags": []
|
|
543
|
+
}
|
|
394
544
|
}
|
|
395
545
|
};
|
|
396
546
|
}
|
|
547
|
+
static get watchers() {
|
|
548
|
+
return [{
|
|
549
|
+
"propName": "data",
|
|
550
|
+
"methodName": "watchData"
|
|
551
|
+
}];
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
function isLastCellInClue(clue, cell) {
|
|
555
|
+
return getClueLastCell(clue).eq(Vec2.from(cell));
|
|
556
|
+
}
|
|
557
|
+
function isFirstCellInWord(clue, cell) {
|
|
558
|
+
return Vec2.from(clue).eq(Vec2.from(cell));
|
|
397
559
|
}
|
|
398
|
-
function
|
|
399
|
-
|
|
400
|
-
word.x + (word.orientation === 'horizontal' ? (word.word.length - 1) : 0),
|
|
401
|
-
word.y + (word.orientation === 'vertical' ? (word.word.length - 1) : 0),
|
|
402
|
-
];
|
|
403
|
-
const result = cell.x === lastCellXY[0] && cell.y === lastCellXY[1];
|
|
404
|
-
return result;
|
|
560
|
+
function getClueLastCell(clue) {
|
|
561
|
+
return new Vec2(clue.x + (clue.orientation === 'horizontal' ? (clue.word.length - 1) : 0), clue.y + (clue.orientation === 'vertical' ? (clue.word.length - 1) : 0));
|
|
405
562
|
}
|
|
@@ -13,3 +13,9 @@ export function isKeyboardEventLetter(event) {
|
|
|
13
13
|
const key = event.key.toLowerCase();
|
|
14
14
|
return /[0-9a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u024F]/.test(key);
|
|
15
15
|
}
|
|
16
|
+
export function isInputEventLetter(event) {
|
|
17
|
+
if (event.data.length !== 1)
|
|
18
|
+
return false;
|
|
19
|
+
const key = event.data.toLowerCase();
|
|
20
|
+
return /[0-9a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u024F]/.test(key);
|
|
21
|
+
}
|