@mborecki/crossword 0.0.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.
Files changed (55) hide show
  1. package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
  2. package/dist/cjs/index-CwHIXXW5.js +61 -0
  3. package/dist/cjs/index-TyGpRn4d.js +3159 -0
  4. package/dist/cjs/index.cjs.js +9 -0
  5. package/dist/cjs/loader.cjs.js +13 -0
  6. package/dist/cjs/mb-crossword.cjs.entry.js +323 -0
  7. package/dist/cjs/mb-crossword.cjs.js +25 -0
  8. package/dist/collection/collection-manifest.json +12 -0
  9. package/dist/collection/components/crossword/cell.js +8 -0
  10. package/dist/collection/components/crossword/clue.js +6 -0
  11. package/dist/collection/components/crossword/mb-crossword.css +57 -0
  12. package/dist/collection/components/crossword/mb-crossword.js +405 -0
  13. package/dist/collection/components/crossword/types.js +1 -0
  14. package/dist/collection/index.js +10 -0
  15. package/dist/collection/utils/utils.js +15 -0
  16. package/dist/collection/utils/utils.test.js +52 -0
  17. package/dist/components/index.d.ts +35 -0
  18. package/dist/components/index.js +1 -0
  19. package/dist/components/mb-crossword.d.ts +11 -0
  20. package/dist/components/mb-crossword.js +1 -0
  21. package/dist/esm/app-globals-DQuL1Twl.js +3 -0
  22. package/dist/esm/index-0i8AYf_G.js +56 -0
  23. package/dist/esm/index-B4XIBYtu.js +3152 -0
  24. package/dist/esm/index.js +1 -0
  25. package/dist/esm/loader.js +11 -0
  26. package/dist/esm/mb-crossword.entry.js +321 -0
  27. package/dist/esm/mb-crossword.js +21 -0
  28. package/dist/index.cjs.js +1 -0
  29. package/dist/index.js +1 -0
  30. package/dist/mb-crossword/index.esm.js +1 -0
  31. package/dist/mb-crossword/mb-crossword.esm.js +1 -0
  32. package/dist/mb-crossword/p-0i8AYf_G.js +1 -0
  33. package/dist/mb-crossword/p-5b227b8e.entry.js +1 -0
  34. package/dist/mb-crossword/p-B4XIBYtu.js +2 -0
  35. package/dist/mb-crossword/p-DQuL1Twl.js +1 -0
  36. package/dist/types/components/crossword/cell.d.ts +7 -0
  37. package/dist/types/components/crossword/clue.d.ts +7 -0
  38. package/dist/types/components/crossword/mb-crossword.d.ts +40 -0
  39. package/dist/types/components/crossword/types.d.ts +20 -0
  40. package/dist/types/components.d.ts +50 -0
  41. package/dist/types/index.d.ts +11 -0
  42. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/apps/crossword/vitest.config.d.ts +2 -0
  43. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/vec2/src/vec2.d.ts +17 -0
  44. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/vec2/src/vec2.test.d.ts +1 -0
  45. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/vec2/vitest.config.d.ts +2 -0
  46. package/dist/types/stencil-public-runtime.d.ts +1839 -0
  47. package/dist/types/utils/utils.d.ts +4 -0
  48. package/dist/types/utils/utils.test.d.ts +1 -0
  49. package/dist/vitest.config.js +4 -0
  50. package/loader/cdn.js +1 -0
  51. package/loader/index.cjs.js +1 -0
  52. package/loader/index.d.ts +24 -0
  53. package/loader/index.es2017.js +1 -0
  54. package/loader/index.js +2 -0
  55. package/package.json +53 -0
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-CwHIXXW5.js');
4
+
5
+
6
+
7
+ exports.Vec2fromIndex = index.Vec2fromIndex;
8
+ exports.indexFromXY = index.indexFromXY;
9
+ exports.isKeyboardEventLetter = index.isKeyboardEventLetter;
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-TyGpRn4d.js');
4
+ var appGlobals = require('./app-globals-V2Kpy_OQ.js');
5
+
6
+ const defineCustomElements = async (win, options) => {
7
+ if (typeof window === 'undefined') return undefined;
8
+ await appGlobals.globalScripts();
9
+ return index.bootstrapLazy([["mb-crossword.cjs",[[513,"mb-crossword",{"init":[4],"data":[16],"hWords":[32],"vWords":[32],"currentClueId":[32],"currentClue":[32],"isFocused":[32],"selectedCell":[32],"boardWidth":[32],"boardHeight":[32],"cells":[32],"initGame":[64]}]]]], options);
10
+ };
11
+
12
+ exports.setNonce = index.setNonce;
13
+ exports.defineCustomElements = defineCustomElements;
@@ -0,0 +1,323 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-TyGpRn4d.js');
4
+ var index$1 = require('./index-CwHIXXW5.js');
5
+
6
+ function Clue({ isCurrent, word, onPointerDown }) {
7
+ return index.h("p", { onPointerDown: onPointerDown, part: "clue", class: {
8
+ "--current": isCurrent
9
+ } }, word.clue);
10
+ }
11
+
12
+ function Cell({ data, isInCurrentClue, isSelected }) {
13
+ return index.h("div", { part: "cell", class: {
14
+ "--blocked": data.isBlocked,
15
+ '--in-current-clue': isInCurrentClue,
16
+ '--selected': isSelected,
17
+ } }, index.h("div", { class: "_inner", style: { position: 'absolute', width: '100%' } }, data.value));
18
+ }
19
+
20
+ const mbCrosswordCss = () => `*[part=main]{display:grid;grid-template-areas:"clues board";grid-template-columns:1fr 1fr}*[part=main].--focused{background:lightgrey}[part=clues]{grid-area:clues;display:grid;grid-template-columns:1fr 1fr}[part=clue].--current{background:lightcyan}[part=board]{grid-area:board;display:grid}[part=cell]{aspect-ratio:1;background:#d9d9d9;position:relative;container-type:size}[part=cell]:nth-child(2n){background:#999}[part=cell].--blocked{background:black}[part=cell].--in-current-clue{box-shadow:inset 0 0 2px 2px lightblue}[part=cell].--selected{background:lightblue}[part=cell] ._inner{position:absolute;top:0;left:0;right:0;bottom:0;display:grid;place-content:center;text-transform:uppercase;font-size:80cqh}[part=preview]{display:none}`;
21
+
22
+ const MBCrossword = class {
23
+ constructor(hostRef) {
24
+ index.registerInstance(this, hostRef);
25
+ }
26
+ init = true;
27
+ data;
28
+ hWords = [];
29
+ vWords = [];
30
+ currentClueId = null;
31
+ currentClue = null;
32
+ isFocused = false;
33
+ selectedCell = null;
34
+ componentWillLoad() {
35
+ if (this.init && this.data) {
36
+ this.initGame();
37
+ }
38
+ }
39
+ get allWords() {
40
+ return [
41
+ ...this.hWords,
42
+ ...this.vWords
43
+ ];
44
+ }
45
+ async initGame(data = this.data) {
46
+ if (!data.words) {
47
+ throw new Error('Words definition missing');
48
+ }
49
+ this.hWords = [];
50
+ this.vWords = [];
51
+ data.words.forEach((w, index) => {
52
+ const idSeed = Math.random();
53
+ if (typeof w.id === 'undefined') {
54
+ w.id = `${idSeed}_${index}`;
55
+ }
56
+ if (w.orientation === 'horizontal') {
57
+ this.hWords = [...this.hWords, w];
58
+ }
59
+ if (w.orientation === 'vertical') {
60
+ this.vWords = [...this.vWords, w];
61
+ }
62
+ });
63
+ this.buildBoard();
64
+ }
65
+ boardWidth = 0;
66
+ boardHeight = 0;
67
+ cells = [];
68
+ buildBoard() {
69
+ let boardWidth = 0;
70
+ let boardHeight = 0;
71
+ this.allWords.forEach((w) => {
72
+ if (w.orientation === 'horizontal') {
73
+ boardWidth = Math.max(boardWidth, w.x + w.word.length);
74
+ boardHeight = Math.max(boardHeight, w.y + 1);
75
+ }
76
+ if (w.orientation === 'vertical') {
77
+ boardWidth = Math.max(boardWidth, w.x + 1);
78
+ boardHeight = Math.max(boardHeight, w.y + w.word.length);
79
+ }
80
+ });
81
+ const cells = Array(boardHeight * boardWidth).fill(null).map((_, index) => {
82
+ const [x, y] = index$1.Vec2fromIndex(index, boardWidth);
83
+ return {
84
+ index,
85
+ x,
86
+ y,
87
+ value: null,
88
+ isCurrent: false,
89
+ isInCurrentWord: false,
90
+ isBlocked: true
91
+ };
92
+ });
93
+ this.allWords.forEach((w) => {
94
+ if (w.orientation === 'horizontal') {
95
+ for (let i = 0; i < w.word.length; i++) {
96
+ const v = index$1.Vec2.from(w);
97
+ const cellIndex = index$1.indexFromXY(new index$1.Vec2(v.x + i, v.y), boardWidth);
98
+ cells[cellIndex].isBlocked = false;
99
+ }
100
+ }
101
+ if (w.orientation === 'vertical') {
102
+ for (let i = 0; i < w.word.length; i++) {
103
+ const v = index$1.Vec2.from(w);
104
+ const cellIndex = index$1.indexFromXY(new index$1.Vec2(v.x, v.y + i), boardWidth);
105
+ cells[cellIndex].isBlocked = false;
106
+ }
107
+ }
108
+ });
109
+ this.cells = cells;
110
+ this.boardWidth = boardWidth;
111
+ this.boardHeight = boardHeight;
112
+ }
113
+ isInClue(xy, clue = this.currentClue) {
114
+ if (clue === null)
115
+ return false;
116
+ if (xy.x !== clue.x && xy.y !== clue.y)
117
+ return false;
118
+ if (clue.orientation === 'horizontal') {
119
+ if (xy.y !== clue.y)
120
+ return false;
121
+ if (xy.x < clue.x)
122
+ return false;
123
+ if (xy.x >= clue.x + clue.word.length)
124
+ return false;
125
+ return true;
126
+ }
127
+ if (clue.orientation === 'vertical') {
128
+ if (xy.x !== clue.x)
129
+ return false;
130
+ if (xy.y < clue.y)
131
+ return false;
132
+ if (xy.y >= clue.y + clue.word.length)
133
+ return false;
134
+ return true;
135
+ }
136
+ }
137
+ isSelectedCell(cell) {
138
+ if (!this.selectedCell)
139
+ return false;
140
+ return cell.x === this.selectedCell.x && cell.y === this.selectedCell.y;
141
+ }
142
+ getNextClueId() {
143
+ if (!this.currentClueId) {
144
+ return this.allWords[0]?.id ?? null;
145
+ }
146
+ const currentIndex = this.allWords.findIndex(w => w.id === this.currentClueId);
147
+ if (currentIndex < 0) {
148
+ return this.allWords[0]?.id ?? null;
149
+ }
150
+ return this.allWords[currentIndex + 1]?.id ?? null;
151
+ }
152
+ getPrevClueId() {
153
+ if (!this.currentClueId) {
154
+ return this.allWords[0]?.id ?? null;
155
+ }
156
+ const currentIndex = this.allWords.findIndex(w => w.id === this.currentClueId);
157
+ if (currentIndex < 0) {
158
+ return this.allWords[0]?.id ?? null;
159
+ }
160
+ return this.allWords[currentIndex - 1]?.id ?? null;
161
+ }
162
+ inputLetter(char) {
163
+ if (!this.selectedCell)
164
+ return;
165
+ this.selectedCell.value = char;
166
+ this.selectNextCell();
167
+ index.forceUpdate(this);
168
+ }
169
+ selectNextCell() {
170
+ if (!this.selectedCell || !this.currentClue)
171
+ return;
172
+ const currentOrientation = this.currentClue.orientation;
173
+ if (isLastCellInWord(this.currentClue, this.selectedCell)) {
174
+ const nextClueId = this.getNextClueId();
175
+ if (nextClueId) {
176
+ this.selectClue(nextClueId);
177
+ }
178
+ else {
179
+ this.selectClue(this.hWords[0]?.id ?? this.vWords[0]?.id);
180
+ }
181
+ return;
182
+ }
183
+ if (currentOrientation === 'horizontal') {
184
+ this.selectCellByXY(new index$1.Vec2(this.selectedCell.x + 1, this.selectedCell.y));
185
+ }
186
+ if (currentOrientation === 'vertical') {
187
+ this.selectCellByXY(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y + 1));
188
+ }
189
+ }
190
+ onFocusin() {
191
+ this.isFocused = true;
192
+ if (!this.currentClueId) {
193
+ this.currentClueId = this.allWords[0]?.id ?? null;
194
+ }
195
+ }
196
+ onFocusOut() {
197
+ this.isFocused = false;
198
+ }
199
+ selectClue(id, { row, col } = {}) {
200
+ if (!id)
201
+ return;
202
+ this.currentClueId = id;
203
+ const clue = this.allWords.find(w => w.id === id);
204
+ if (!clue) {
205
+ this.currentClueId = null;
206
+ this.currentClue = null;
207
+ }
208
+ this.currentClue = clue;
209
+ const selectCell = [clue.x, clue.y];
210
+ if (typeof row !== 'undefined' && clue.orientation === 'vertical') {
211
+ if (row >= clue.y && row < clue.y + clue.word.length) {
212
+ selectCell[1] = row;
213
+ }
214
+ }
215
+ if (typeof col !== 'undefined' && clue.orientation === 'horizontal') {
216
+ if (col >= clue.x && col < clue.x + clue.word.length) {
217
+ selectCell[0] = col;
218
+ }
219
+ }
220
+ this.selectCellByXY(index$1.Vec2.from(selectCell));
221
+ }
222
+ selectCellByXY(v) {
223
+ const selectCellIndex = index$1.indexFromXY(v, this.boardWidth);
224
+ this.selectedCell = this.cells[selectCellIndex] ?? null;
225
+ }
226
+ findNonblockedCell(source, vector) {
227
+ const pointer = new index$1.Vec2(source[0] + vector[0], source[1] + vector[1]);
228
+ const maxIterations = this.boardWidth * this.boardHeight;
229
+ let iterations = 0;
230
+ while (this.isCellBlocked(pointer) && iterations < maxIterations) {
231
+ iterations++;
232
+ pointer[0] += vector[0];
233
+ pointer[1] += vector[1];
234
+ if (pointer[0] < 0) {
235
+ pointer[0] = this.boardWidth - 1;
236
+ }
237
+ if (pointer[0] >= this.boardWidth) {
238
+ pointer[0] = 0;
239
+ }
240
+ if (pointer[1] < 0) {
241
+ pointer[1] = this.boardHeight - 1;
242
+ }
243
+ if (pointer[1] >= this.boardHeight) {
244
+ pointer[1] = 0;
245
+ }
246
+ }
247
+ return pointer;
248
+ }
249
+ isCellBlocked(v) {
250
+ const cell = this.cells[index$1.indexFromXY(v, this.boardWidth)];
251
+ return cell?.isBlocked ?? true;
252
+ }
253
+ selectClueByXY(v) {
254
+ const clues = this.allWords.filter(w => this.isInClue(v, w));
255
+ if (!clues.length) {
256
+ return;
257
+ }
258
+ const betterClue = clues.find(c => c.orientation === this.currentClue?.orientation);
259
+ this.selectClue(betterClue?.id ?? clues[0].id, { row: v.y, col: v.x });
260
+ }
261
+ onKeyPress(event) {
262
+ console.log(event);
263
+ if (event.key === 'Tab') {
264
+ const nextClue = event.shiftKey ? this.getPrevClueId() : this.getNextClueId();
265
+ if (nextClue) {
266
+ event.preventDefault();
267
+ this.selectClue(nextClue);
268
+ }
269
+ }
270
+ if (index$1.isKeyboardEventLetter(event)) {
271
+ this.inputLetter(event.key.toLowerCase()[0]);
272
+ }
273
+ if (this.selectedCell) {
274
+ switch (event.key) {
275
+ case 'ArrowLeft':
276
+ this.selectClueByXY(this.findNonblockedCell(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y), new index$1.Vec2(-1, 0)));
277
+ event.preventDefault();
278
+ return;
279
+ case 'ArrowRight':
280
+ this.selectClueByXY(this.findNonblockedCell(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y), new index$1.Vec2(1, 0)));
281
+ event.preventDefault();
282
+ return;
283
+ case 'ArrowUp':
284
+ this.selectClueByXY(this.findNonblockedCell(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y), new index$1.Vec2(0, -1)));
285
+ event.preventDefault();
286
+ return;
287
+ case 'ArrowDown':
288
+ this.selectClueByXY(this.findNonblockedCell(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y), new index$1.Vec2(0, 1)));
289
+ event.preventDefault();
290
+ return;
291
+ }
292
+ }
293
+ }
294
+ render() {
295
+ return index.h("div", { key: 'e298ac6f3a1d95bc41c4854b39600f8ac7f1696d', part: "main", class: {
296
+ "--focused": this.isFocused
297
+ }, onFocusin: this.onFocusin.bind(this), onFocusout: this.onFocusOut.bind(this), tabIndex: 0, onKeyDown: this.onKeyPress.bind(this) }, index.h("div", { key: '74be935779266effb4605f2aa5883bf564610bc0', part: "clues" }, index.h("div", { key: '125d8938e4f084562b54794158074bdaeda722b5', part: "clue-list" }, this.hWords.map(w => {
298
+ const isCurrent = w.id === this.currentClueId;
299
+ return index.h(Clue, { word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
300
+ })), index.h("div", { key: '4469227db5156a2d0b30e4dc7ef9ea8f8a1fc3bc', part: "clue-list" }, this.vWords.map(w => {
301
+ const isCurrent = w.id === this.currentClueId;
302
+ return index.h(Clue, { word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
303
+ }))), index.h("div", { key: '965b2e99d1fbf273907f722e8b15749fbd728070', part: "board", style: {
304
+ '--test': '12',
305
+ 'grid-template-columns': `repeat(${this.boardWidth}, 1fr)`
306
+ } }, this.cells.map(cell => {
307
+ const isInCurrentClue = this.isInClue(cell);
308
+ const isSelected = this.isSelectedCell(cell);
309
+ return index.h(Cell, { isInCurrentClue: isInCurrentClue, isSelected: isSelected, data: cell });
310
+ })), index.h("div", { key: '3d97bcc65c5eb1d25b60aa5183a7c63f6eecebf9', part: "preview" }, "Tu bedzie podgl\u0105d: ", this.currentClueId));
311
+ }
312
+ };
313
+ function isLastCellInWord(word, cell) {
314
+ const lastCellXY = [
315
+ word.x + (word.orientation === 'horizontal' ? (word.word.length - 1) : 0),
316
+ word.y + (word.orientation === 'vertical' ? (word.word.length - 1) : 0),
317
+ ];
318
+ const result = cell.x === lastCellXY[0] && cell.y === lastCellXY[1];
319
+ return result;
320
+ }
321
+ MBCrossword.style = mbCrosswordCss();
322
+
323
+ exports.mb_crossword = MBCrossword;
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-TyGpRn4d.js');
4
+ var appGlobals = require('./app-globals-V2Kpy_OQ.js');
5
+
6
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
7
+ /*
8
+ Stencil Client Patch Browser v4.41.0 | MIT Licensed | https://stenciljs.com
9
+ */
10
+
11
+ var patchBrowser = () => {
12
+ const importMeta = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('mb-crossword.cjs.js', document.baseURI).href));
13
+ const opts = {};
14
+ if (importMeta !== "") {
15
+ opts.resourcesUrl = new URL(".", importMeta).href;
16
+ }
17
+ return index.promiseResolve(opts);
18
+ };
19
+
20
+ patchBrowser().then(async (options) => {
21
+ await appGlobals.globalScripts();
22
+ return index.bootstrapLazy([["mb-crossword.cjs",[[513,"mb-crossword",{"init":[4],"data":[16],"hWords":[32],"vWords":[32],"currentClueId":[32],"currentClue":[32],"isFocused":[32],"selectedCell":[32],"boardWidth":[32],"boardHeight":[32],"cells":[32],"initGame":[64]}]]]], options);
23
+ });
24
+
25
+ exports.setNonce = index.setNonce;
@@ -0,0 +1,12 @@
1
+ {
2
+ "entries": [
3
+ "components/crossword/mb-crossword.js"
4
+ ],
5
+ "compiler": {
6
+ "name": "@stencil/core",
7
+ "version": "4.41.0",
8
+ "typescriptVersion": "5.8.3"
9
+ },
10
+ "collections": [],
11
+ "bundles": []
12
+ }
@@ -0,0 +1,8 @@
1
+ import { h } from "@stencil/core";
2
+ export function Cell({ data, isInCurrentClue, isSelected }) {
3
+ return h("div", { part: "cell", class: {
4
+ "--blocked": data.isBlocked,
5
+ '--in-current-clue': isInCurrentClue,
6
+ '--selected': isSelected,
7
+ } }, h("div", { class: "_inner", style: { position: 'absolute', width: '100%' } }, data.value));
8
+ }
@@ -0,0 +1,6 @@
1
+ import { h } from "@stencil/core";
2
+ export function Clue({ isCurrent, word, onPointerDown }) {
3
+ return h("p", { onPointerDown: onPointerDown, part: "clue", class: {
4
+ "--current": isCurrent
5
+ } }, word.clue);
6
+ }
@@ -0,0 +1,57 @@
1
+ *[part=main] {
2
+ display: grid;
3
+ grid-template-areas: "clues board";
4
+ grid-template-columns: 1fr 1fr;
5
+ }
6
+ *[part=main].--focused {
7
+ background: lightgrey;
8
+ }
9
+
10
+ [part=clues] {
11
+ grid-area: clues;
12
+ display: grid;
13
+ grid-template-columns: 1fr 1fr;
14
+ }
15
+
16
+ [part=clue].--current {
17
+ background: lightcyan;
18
+ }
19
+
20
+ [part=board] {
21
+ grid-area: board;
22
+ display: grid;
23
+ }
24
+
25
+ [part=cell] {
26
+ aspect-ratio: 1;
27
+ background: #d9d9d9;
28
+ position: relative;
29
+ container-type: size;
30
+ }
31
+ [part=cell]:nth-child(2n) {
32
+ background: #999;
33
+ }
34
+ [part=cell].--blocked {
35
+ background: black;
36
+ }
37
+ [part=cell].--in-current-clue {
38
+ box-shadow: inset 0 0 2px 2px lightblue;
39
+ }
40
+ [part=cell].--selected {
41
+ background: lightblue;
42
+ }
43
+ [part=cell] ._inner {
44
+ position: absolute;
45
+ top: 0;
46
+ left: 0;
47
+ right: 0;
48
+ bottom: 0;
49
+ display: grid;
50
+ place-content: center;
51
+ text-transform: uppercase;
52
+ font-size: 80cqh;
53
+ }
54
+
55
+ [part=preview] {
56
+ display: none;
57
+ }