@mborecki/crossword 0.0.2 → 0.1.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.
Files changed (35) hide show
  1. package/dist/cjs/{index-TyGpRn4d.js → index-BlTGwvVC.js} +63 -2
  2. package/dist/cjs/{index-CwHIXXW5.js → index-CEGyCfpa.js} +29 -1
  3. package/dist/cjs/index.cjs.js +2 -1
  4. package/dist/cjs/loader.cjs.js +2 -2
  5. package/dist/cjs/mb-crossword.cjs.entry.js +139 -38
  6. package/dist/cjs/mb-crossword.cjs.js +2 -2
  7. package/dist/collection/components/crossword/cell.js +7 -2
  8. package/dist/collection/components/crossword/clue.js +2 -2
  9. package/dist/collection/components/crossword/mb-crossword.css +72 -8
  10. package/dist/collection/components/crossword/mb-crossword.js +131 -32
  11. package/dist/collection/utils/utils.js +6 -0
  12. package/dist/components/index.js +1 -1
  13. package/dist/components/mb-crossword.js +1 -1
  14. package/dist/esm/{index-B4XIBYtu.js → index-BGHKtxML.js} +63 -2
  15. package/dist/esm/{index-0i8AYf_G.js → index-Dn3GSx6U.js} +29 -2
  16. package/dist/esm/index.js +1 -1
  17. package/dist/esm/loader.js +3 -3
  18. package/dist/esm/mb-crossword.entry.js +139 -38
  19. package/dist/esm/mb-crossword.js +3 -3
  20. package/dist/mb-crossword/index.esm.js +1 -1
  21. package/dist/mb-crossword/mb-crossword.esm.js +1 -1
  22. package/dist/mb-crossword/p-162bd00d.entry.js +1 -0
  23. package/dist/mb-crossword/{p-B4XIBYtu.js → p-BGHKtxML.js} +2 -2
  24. package/dist/mb-crossword/p-Dn3GSx6U.js +1 -0
  25. package/dist/types/components/crossword/cell.d.ts +3 -1
  26. package/dist/types/components/crossword/clue.d.ts +4 -3
  27. package/dist/types/components/crossword/mb-crossword.d.ts +15 -6
  28. package/dist/types/components/crossword/types.d.ts +13 -2
  29. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/grid/src/grid.d.ts +12 -0
  30. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/grid/vitest.config.d.ts +2 -0
  31. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/vec2/src/vec2.d.ts +9 -2
  32. package/dist/types/utils/utils.d.ts +1 -0
  33. package/package.json +6 -1
  34. package/dist/mb-crossword/p-0i8AYf_G.js +0 -1
  35. package/dist/mb-crossword/p-5b227b8e.entry.js +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const NAMESPACE = 'mb-crossword';
4
- const BUILD = /* mb-crossword */ { hotModuleReplacement: false, hydratedSelectorName: "hydrated", lazyLoad: true, propChangeCallback: false, state: true, updatable: true};
4
+ const BUILD = /* mb-crossword */ { hotModuleReplacement: false, hydratedSelectorName: "hydrated", lazyLoad: true, propChangeCallback: true, state: true, updatable: true};
5
5
 
6
6
  /*
7
7
  Stencil Client Platform v4.41.0 | MIT Licensed | https://stenciljs.com
@@ -1848,6 +1848,9 @@ var globalStyleSheet;
1848
1848
  function createShadowRoot(cmpMeta) {
1849
1849
  var _a;
1850
1850
  const opts = { mode: "open" };
1851
+ {
1852
+ opts.delegatesFocus = !!(cmpMeta.$flags$ & 16 /* shadowDelegatesFocus */);
1853
+ }
1851
1854
  const shadowRoot = this.attachShadow(opts);
1852
1855
  if (globalStyleSheet === void 0) globalStyleSheet = (_a = createStyleSheetIfNeededAndSupported()) != null ? _a : null;
1853
1856
  if (globalStyleSheet) {
@@ -2196,7 +2199,11 @@ var setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialRen
2196
2199
  }
2197
2200
  }
2198
2201
  }
2199
- } else if (memberName === "key") ; else if ((!isProp ) && memberName[0] === "o" && memberName[1] === "n") {
2202
+ } else if (memberName === "key") ; else if (memberName === "ref") {
2203
+ if (newValue) {
2204
+ newValue(elm);
2205
+ }
2206
+ } else if ((!isProp ) && memberName[0] === "o" && memberName[1] === "n") {
2200
2207
  if (memberName[2] === "-") {
2201
2208
  memberName = memberName.slice(3);
2202
2209
  } else if (isMemberInElement(win, ln)) {
@@ -2357,6 +2364,7 @@ var removeVnodes = (vnodes, startIdx, endIdx) => {
2357
2364
  const vnode = vnodes[index];
2358
2365
  if (vnode) {
2359
2366
  const elm = vnode.$elm$;
2367
+ nullifyVNodeRefs(vnode);
2360
2368
  if (elm) {
2361
2369
  elm.remove();
2362
2370
  }
@@ -2486,6 +2494,12 @@ var patch = (oldVNode, newVNode2, isInitialRender = false) => {
2486
2494
  elm.data = text;
2487
2495
  }
2488
2496
  };
2497
+ var nullifyVNodeRefs = (vNode) => {
2498
+ {
2499
+ vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(null);
2500
+ vNode.$children$ && vNode.$children$.map(nullifyVNodeRefs);
2501
+ }
2502
+ };
2489
2503
  var insertBefore = (parent, newNode, reference, isInitialLoad) => {
2490
2504
  if (typeof newNode["s-sn"] === "string") {
2491
2505
  parent.insertBefore(newNode, reference);
@@ -2709,6 +2723,7 @@ var setValue = (ref, propName, newVal, cmpMeta) => {
2709
2723
  `Couldn't find host element for "${cmpMeta.$tagName$}" as it is unknown to this Stencil runtime. This usually happens when integrating a 3rd party Stencil component with another Stencil component or application. Please reach out to the maintainers of the 3rd party Stencil component or report this on the Stencil Discord server (https://chat.stenciljs.com) or comment on this similar [GitHub issue](https://github.com/stenciljs/core/issues/5457).`
2710
2724
  );
2711
2725
  }
2726
+ const elm = hostRef.$hostElement$ ;
2712
2727
  const oldVal = hostRef.$instanceValues$.get(propName);
2713
2728
  const flags = hostRef.$flags$;
2714
2729
  const instance = hostRef.$lazyInstance$ ;
@@ -2719,6 +2734,27 @@ var setValue = (ref, propName, newVal, cmpMeta) => {
2719
2734
  const didValueChange = newVal !== oldVal && !areBothNaN;
2720
2735
  if ((!(flags & 8 /* isConstructingInstance */) || oldVal === void 0) && didValueChange) {
2721
2736
  hostRef.$instanceValues$.set(propName, newVal);
2737
+ if (cmpMeta.$watchers$) {
2738
+ const watchMethods = cmpMeta.$watchers$[propName];
2739
+ if (watchMethods) {
2740
+ watchMethods.map((watcher) => {
2741
+ try {
2742
+ const [[watchMethodName, watcherFlags]] = Object.entries(watcher);
2743
+ if (flags & 128 /* isWatchReady */ || watcherFlags & 1 /* Immediate */) {
2744
+ if (!instance) {
2745
+ hostRef.$fetchedCbList$.push(() => {
2746
+ hostRef.$lazyInstance$[watchMethodName](newVal, oldVal, propName);
2747
+ });
2748
+ } else {
2749
+ instance[watchMethodName](newVal, oldVal, propName);
2750
+ }
2751
+ }
2752
+ } catch (e) {
2753
+ consoleError(e, elm);
2754
+ }
2755
+ });
2756
+ }
2757
+ }
2722
2758
  if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
2723
2759
  if (instance.componentShouldUpdate) {
2724
2760
  if (instance.componentShouldUpdate(newVal, oldVal, propName) === false) {
@@ -2735,6 +2771,17 @@ var proxyComponent = (Cstr, cmpMeta, flags) => {
2735
2771
  var _a, _b;
2736
2772
  const prototype = Cstr.prototype;
2737
2773
  if (cmpMeta.$members$ || BUILD.propChangeCallback) {
2774
+ {
2775
+ if (Cstr.watchers && !cmpMeta.$watchers$) {
2776
+ cmpMeta.$watchers$ = Cstr.watchers;
2777
+ }
2778
+ if (Cstr.deserializers && !cmpMeta.$deserializers$) {
2779
+ cmpMeta.$deserializers$ = Cstr.deserializers;
2780
+ }
2781
+ if (Cstr.serializers && !cmpMeta.$serializers$) {
2782
+ cmpMeta.$serializers$ = Cstr.serializers;
2783
+ }
2784
+ }
2738
2785
  const members = Object.entries((_a = cmpMeta.$members$) != null ? _a : {});
2739
2786
  members.map(([memberName, [memberFlags]]) => {
2740
2787
  if ((memberFlags & 31 /* Prop */ || (flags & 2 /* proxyState */) && memberFlags & 32 /* State */)) {
@@ -2895,6 +2942,11 @@ var initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
2895
2942
  throw new Error(`Constructor for "${cmpMeta.$tagName$}#${hostRef.$modeName$}" was not found`);
2896
2943
  }
2897
2944
  if (!Cstr.isProxied) {
2945
+ {
2946
+ cmpMeta.$watchers$ = Cstr.watchers;
2947
+ cmpMeta.$serializers$ = Cstr.serializers;
2948
+ cmpMeta.$deserializers$ = Cstr.deserializers;
2949
+ }
2898
2950
  proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
2899
2951
  Cstr.isProxied = true;
2900
2952
  }
@@ -2910,6 +2962,9 @@ var initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
2910
2962
  {
2911
2963
  hostRef.$flags$ &= -9 /* isConstructingInstance */;
2912
2964
  }
2965
+ {
2966
+ hostRef.$flags$ |= 128 /* isWatchReady */;
2967
+ }
2913
2968
  endNewInstance();
2914
2969
  {
2915
2970
  fireConnectedCallback(hostRef.$lazyInstance$, elm);
@@ -3032,6 +3087,7 @@ var bootstrapLazy = (lazyBundles, options = {}) => {
3032
3087
  let hasSlotRelocation = false;
3033
3088
  lazyBundles.map((lazyBundle) => {
3034
3089
  lazyBundle[1].map((compactMeta) => {
3090
+ var _a2, _b, _c;
3035
3091
  const cmpMeta = {
3036
3092
  $flags$: compactMeta[0],
3037
3093
  $tagName$: compactMeta[1],
@@ -3044,6 +3100,11 @@ var bootstrapLazy = (lazyBundles, options = {}) => {
3044
3100
  {
3045
3101
  cmpMeta.$members$ = compactMeta[2];
3046
3102
  }
3103
+ {
3104
+ cmpMeta.$watchers$ = (_a2 = compactMeta[4]) != null ? _a2 : {};
3105
+ cmpMeta.$serializers$ = (_b = compactMeta[5]) != null ? _b : {};
3106
+ cmpMeta.$deserializers$ = (_c = compactMeta[6]) != null ? _c : {};
3107
+ }
3047
3108
  const tagName = transformTag(cmpMeta.$tagName$);
3048
3109
  const HostElement = class extends HTMLElement {
3049
3110
  ["s-p"];
@@ -15,6 +15,18 @@ class Vec2 {
15
15
  set 1(y) {
16
16
  this.y = y;
17
17
  }
18
+ get width() {
19
+ return this.x;
20
+ }
21
+ set width(x) {
22
+ this.x = x;
23
+ }
24
+ get height() {
25
+ return this.y;
26
+ }
27
+ set height(y) {
28
+ this.y = y;
29
+ }
18
30
  get xy() {
19
31
  return [this.x, this.y];
20
32
  }
@@ -26,12 +38,21 @@ class Vec2 {
26
38
  this.x = x;
27
39
  this.y = y;
28
40
  }
41
+ add(v) {
42
+ return new Vec2(this.x + v.x, this.y + v.y);
43
+ }
44
+ eq(v) {
45
+ return this.x === v.x && this.y === v.y;
46
+ }
47
+ clone() {
48
+ return new Vec2(this.x, this.y);
49
+ }
29
50
  static from(source) {
30
51
  if (typeof source === 'number') {
31
52
  return new Vec2(source, source);
32
53
  }
33
54
  if (Array.isArray(source)) {
34
- return new Vec2(source[0], source[1]);
55
+ return new Vec2(source[0] ?? 0, source[1] ?? 0);
35
56
  }
36
57
  if (typeof source === 'object' && typeof source.x === 'number' && typeof source.y === 'number') {
37
58
  return new Vec2(source.x, source.y);
@@ -54,8 +75,15 @@ function isKeyboardEventLetter(event) {
54
75
  const key = event.key.toLowerCase();
55
76
  return /[0-9a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u024F]/.test(key);
56
77
  }
78
+ function isInputEventLetter(event) {
79
+ if (event.data.length !== 1)
80
+ return false;
81
+ const key = event.data.toLowerCase();
82
+ return /[0-9a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u024F]/.test(key);
83
+ }
57
84
 
58
85
  exports.Vec2 = Vec2;
59
86
  exports.Vec2fromIndex = Vec2fromIndex;
60
87
  exports.indexFromXY = indexFromXY;
88
+ exports.isInputEventLetter = isInputEventLetter;
61
89
  exports.isKeyboardEventLetter = isKeyboardEventLetter;
@@ -1,9 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-CwHIXXW5.js');
3
+ var index = require('./index-CEGyCfpa.js');
4
4
 
5
5
 
6
6
 
7
7
  exports.Vec2fromIndex = index.Vec2fromIndex;
8
8
  exports.indexFromXY = index.indexFromXY;
9
+ exports.isInputEventLetter = index.isInputEventLetter;
9
10
  exports.isKeyboardEventLetter = index.isKeyboardEventLetter;
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-TyGpRn4d.js');
3
+ var index = require('./index-BlTGwvVC.js');
4
4
  var appGlobals = require('./app-globals-V2Kpy_OQ.js');
5
5
 
6
6
  const defineCustomElements = async (win, options) => {
7
7
  if (typeof window === 'undefined') return undefined;
8
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);
9
+ return index.bootstrapLazy([["mb-crossword.cjs",[[529,"mb-crossword",{"init":[4],"data":[16],"hWords":[32],"vWords":[32],"currentClueId":[32],"currentClue":[32],"isFocused":[32],"selectedCell":[32],"specialBorders":[32],"specialCells":[32],"boardWidth":[32],"boardHeight":[32],"cells":[32],"initGame":[64]},null,{"data":[{"watchData":0}]}]]]], options);
10
10
  };
11
11
 
12
12
  exports.setNonce = index.setNonce;
@@ -1,23 +1,28 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-TyGpRn4d.js');
4
- var index$1 = require('./index-CwHIXXW5.js');
3
+ var index = require('./index-BlTGwvVC.js');
4
+ var index$1 = require('./index-CEGyCfpa.js');
5
5
 
6
- function Clue({ isCurrent, word, onPointerDown }) {
6
+ function Clue({ isCurrent, word, onPointerDown, preview }) {
7
7
  return index.h("p", { onPointerDown: onPointerDown, part: "clue", class: {
8
8
  "--current": isCurrent
9
- } }, word.clue);
9
+ } }, word.clue, index.h("span", { class: "preview" }, preview));
10
10
  }
11
11
 
12
- function Cell({ data, isInCurrentClue, isSelected }) {
13
- return index.h("div", { part: "cell", class: {
12
+ function Cell({ data, isInCurrentClue, isSelected, isSpecial, onPointerDown }) {
13
+ return index.h("div", { onPointerDown: onPointerDown, part: "cell", class: {
14
14
  "--blocked": data.isBlocked,
15
15
  '--in-current-clue': isInCurrentClue,
16
16
  '--selected': isSelected,
17
+ '--alt': !((data.x + data.y) % 2),
18
+ '--special': isSpecial
19
+ }, style: {
20
+ "--x": `${data.x}`,
21
+ "--y": `${data.y}`
17
22
  } }, index.h("div", { class: "_inner", style: { position: 'absolute', width: '100%' } }, data.value));
18
23
  }
19
24
 
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}`;
25
+ const mbCrosswordCss = () => `*[part=main]{position:relative;display:grid;grid-template-areas:"board" "clues";grid-template-columns:1fr}@media (min-width: 768px){*[part=main]{grid-template-areas:"clues board" "clues .";grid-template-columns:1fr 1fr}}*[part=main].--focused{background:lightgrey}*[part=main] input.dummy{pointer-events:none;opacity:0.2;z-index:100;grid-area:board}[part=clues]{grid-area:clues;display:grid;grid-template-columns:1fr 1fr}[part=clue].--current{background:lightcyan;position:sticky;bottom:0;left:0;right:0}[part=clue] .preview{font-weight:bold;letter-spacing:0.2em;text-align:center;display:block;text-transform:uppercase}[part=board]{grid-area:board;display:block;position:relative;container-type:size;background:darkgoldenrod;--border:1px;--cell-width:calc((100cqw - var(--border)) / var(--board-width, 10))}[part=cell]{display:block;width:calc(var(--cell-width) - var(--border));aspect-ratio:1;background:#d9d9d9;position:absolute;container-type:size;top:calc(var(--y, 0) * var(--cell-width));left:calc(var(--x, 0) * var(--cell-width));border:var(--border) solid red}[part=cell].--alt{background:#999}[part=cell].--in-current-clue{box-shadow:inset 0 0 2px 2px lightblue}[part=cell].--selected{background:lightblue}[part=cell].--special{background:lightgreen}[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}[part=special-border]{display:block;background:black;position:absolute;z-index:100;--s-border:max(2px, var(--border))}[part=special-border].left,[part=special-border].right{width:var(--s-border);height:calc(var(--cell-width) - var(--border));top:calc(var(--y, 0) * var(--cell-width) + var(--border))}[part=special-border].left{left:calc(var(--x, 0) * var(--cell-width) - var(--s-border) / 2)}[part=special-border].right{left:calc((var(--x, 0) + 1) * var(--cell-width) - var(--s-border) / 2)}[part=special-border].top,[part=special-border].bottom{width:calc(var(--cell-width) - var(--border));height:var(--s-border);left:calc(var(--x, 0) * var(--cell-width) + var(--border))}[part=special-border].top{top:calc(var(--y, 0) * var(--cell-width))}[part=special-border].bottom{top:calc((var(--y, 0) + 1) * var(--cell-width))}`;
21
26
 
22
27
  const MBCrossword = class {
23
28
  constructor(hostRef) {
@@ -25,6 +30,7 @@ const MBCrossword = class {
25
30
  }
26
31
  init = true;
27
32
  data;
33
+ textInput;
28
34
  hWords = [];
29
35
  vWords = [];
30
36
  currentClueId = null;
@@ -32,6 +38,12 @@ const MBCrossword = class {
32
38
  isFocused = false;
33
39
  selectedCell = null;
34
40
  componentWillLoad() {
41
+ console.log('componentWillLoad', this.init, this.data);
42
+ if (this.init && this.data) {
43
+ this.initGame();
44
+ }
45
+ }
46
+ watchData() {
35
47
  if (this.init && this.data) {
36
48
  this.initGame();
37
49
  }
@@ -43,6 +55,7 @@ const MBCrossword = class {
43
55
  ];
44
56
  }
45
57
  async initGame(data = this.data) {
58
+ console.log('initGame');
46
59
  if (!data.words) {
47
60
  throw new Error('Words definition missing');
48
61
  }
@@ -60,8 +73,12 @@ const MBCrossword = class {
60
73
  this.vWords = [...this.vWords, w];
61
74
  }
62
75
  });
76
+ this.specialBorders = data.specialBorders ?? [];
77
+ this.specialCells = data.specialCells ?? [];
63
78
  this.buildBoard();
64
79
  }
80
+ specialBorders = [];
81
+ specialCells = [];
65
82
  boardWidth = 0;
66
83
  boardHeight = 0;
67
84
  cells = [];
@@ -110,6 +127,9 @@ const MBCrossword = class {
110
127
  this.boardWidth = boardWidth;
111
128
  this.boardHeight = boardHeight;
112
129
  }
130
+ getClueById(id) {
131
+ return this.allWords.find(c => c.id === id) ?? null;
132
+ }
113
133
  isInClue(xy, clue = this.currentClue) {
114
134
  if (clue === null)
115
135
  return false;
@@ -166,25 +186,58 @@ const MBCrossword = class {
166
186
  this.selectNextCell();
167
187
  index.forceUpdate(this);
168
188
  }
189
+ backspace() {
190
+ if (!this.selectedCell)
191
+ return;
192
+ if (this.selectedCell.value) {
193
+ this.selectedCell.value = '';
194
+ this.selectPrevCell();
195
+ }
196
+ else {
197
+ this.selectPrevCell();
198
+ this.selectedCell.value = '';
199
+ }
200
+ index.forceUpdate(this);
201
+ }
169
202
  selectNextCell() {
170
203
  if (!this.selectedCell || !this.currentClue)
171
204
  return;
172
205
  const currentOrientation = this.currentClue.orientation;
173
- if (isLastCellInWord(this.currentClue, this.selectedCell)) {
206
+ if (isLastCellInClue(this.currentClue, this.selectedCell)) {
174
207
  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);
208
+ const clue = this.getClueById(nextClueId);
209
+ if (clue) {
210
+ this.selectClueByXY(index$1.Vec2.from(clue));
211
+ return;
180
212
  }
181
213
  return;
182
214
  }
183
215
  if (currentOrientation === 'horizontal') {
184
- this.selectCellByXY(new index$1.Vec2(this.selectedCell.x + 1, this.selectedCell.y));
216
+ this.selectClueByXY(new index$1.Vec2(this.selectedCell.x + 1, this.selectedCell.y));
217
+ }
218
+ if (currentOrientation === 'vertical') {
219
+ this.selectClueByXY(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y + 1));
220
+ }
221
+ }
222
+ selectPrevCell() {
223
+ if (!this.selectedCell || !this.currentClue)
224
+ return;
225
+ const currentOrientation = this.currentClue.orientation;
226
+ if (isFirstCellInWord(this.currentClue, this.selectedCell)) {
227
+ const prevClueId = this.getPrevClueId();
228
+ const clue = this.getClueById(prevClueId);
229
+ if (clue) {
230
+ const cell = getClueLastCell(clue);
231
+ console.log(cell);
232
+ this.selectClueByXY(cell);
233
+ return;
234
+ }
235
+ }
236
+ if (currentOrientation === 'horizontal') {
237
+ this.selectClueByXY(new index$1.Vec2(this.selectedCell.x - 1, this.selectedCell.y));
185
238
  }
186
239
  if (currentOrientation === 'vertical') {
187
- this.selectCellByXY(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y + 1));
240
+ this.selectClueByXY(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y - 1));
188
241
  }
189
242
  }
190
243
  onFocusin() {
@@ -192,6 +245,7 @@ const MBCrossword = class {
192
245
  if (!this.currentClueId) {
193
246
  this.currentClueId = this.allWords[0]?.id ?? null;
194
247
  }
248
+ this.textInput.focus();
195
249
  }
196
250
  onFocusOut() {
197
251
  this.isFocused = false;
@@ -255,8 +309,27 @@ const MBCrossword = class {
255
309
  if (!clues.length) {
256
310
  return;
257
311
  }
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 });
312
+ if (this.selectedCell && clues.length === 2 && v.eq(index$1.Vec2.from(this.selectedCell))) {
313
+ const betterClue = clues.find(c => c.orientation !== this.currentClue?.orientation);
314
+ this.selectClue(betterClue?.id ?? clues[0].id, { row: v.y, col: v.x });
315
+ }
316
+ else {
317
+ const betterClue = clues.find(c => c.orientation === this.currentClue?.orientation);
318
+ this.selectClue(betterClue?.id ?? clues[0].id, { row: v.y, col: v.x });
319
+ }
320
+ }
321
+ getCluePreview(clue) {
322
+ if (!clue)
323
+ return '_';
324
+ const letters = Array(clue.word.length).fill('_');
325
+ for (let i = 0; i < clue.word.length; i++) {
326
+ const pointer = new index$1.Vec2(clue.x, clue.y).add(clue.orientation === 'vertical' ? new index$1.Vec2(0, 1 * i) : new index$1.Vec2(1 * i, 0));
327
+ const cell = this.cells[index$1.indexFromXY(pointer, this.boardWidth)];
328
+ if (cell.value) {
329
+ letters[i] = cell.value;
330
+ }
331
+ }
332
+ return letters.join('');
260
333
  }
261
334
  onKeyPress(event) {
262
335
  console.log(event);
@@ -267,9 +340,9 @@ const MBCrossword = class {
267
340
  this.selectClue(nextClue);
268
341
  }
269
342
  }
270
- if (index$1.isKeyboardEventLetter(event)) {
271
- this.inputLetter(event.key.toLowerCase()[0]);
272
- }
343
+ // if (isKeyboardEventLetter(event)) {
344
+ // this.inputLetter(event.key.toLowerCase()[0]);
345
+ // }
273
346
  if (this.selectedCell) {
274
347
  switch (event.key) {
275
348
  case 'ArrowLeft':
@@ -288,35 +361,63 @@ const MBCrossword = class {
288
361
  this.selectClueByXY(this.findNonblockedCell(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y), new index$1.Vec2(0, 1)));
289
362
  event.preventDefault();
290
363
  return;
364
+ case 'Backspace':
365
+ console.log('BACKSPACE!');
366
+ this.backspace();
291
367
  }
292
368
  }
293
369
  }
370
+ onInput(event) {
371
+ if (index$1.isInputEventLetter(event)) {
372
+ this.inputLetter(event.data.toLowerCase()[0]);
373
+ }
374
+ this.textInput.value = '';
375
+ }
294
376
  render() {
295
- return index.h("div", { key: 'e298ac6f3a1d95bc41c4854b39600f8ac7f1696d', part: "main", class: {
377
+ return index.h("div", { key: '1dec8e0d58c347be7a44c19c416d3940c37ccf0c', part: "main", class: {
296
378
  "--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 => {
379
+ }, onFocusin: this.onFocusin.bind(this), onFocusout: this.onFocusOut.bind(this) }, index.h("input", { key: '40c9f176b21072bcd084871b9caff7add03c9680', type: "text", class: "dummy", ref: (el) => this.textInput = el, onKeyDown: this.onKeyPress.bind(this), onInput: this.onInput.bind(this) }), index.h("div", { key: '14eb06bad93227192ea299ecd27f12cf58304cea', part: "clues" }, index.h("div", { key: 'e58b0150ff780acd6f770b009d3936a3a7195138', part: "clue-list" }, this.hWords.map(w => {
298
380
  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 => {
381
+ return index.h(Clue, { preview: this.getCluePreview(w), word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
382
+ })), index.h("div", { key: '13c5ca874d95561654096aa09d5b715576d4392d', part: "clue-list" }, this.vWords.map(w => {
301
383
  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 => {
384
+ return index.h(Clue, { preview: this.getCluePreview(w), word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
385
+ }))), index.h("div", { key: '02b43a7a46253d36ad8975d8ab9426af208e82f4', part: "board", style: {
386
+ '--board-width': `${this.boardWidth}`,
387
+ 'grid-template-columns': `repeat(${this.boardWidth}, 1fr)`,
388
+ aspectRatio: `${this.boardWidth / this.boardHeight}`
389
+ } }, this.cells.filter(c => !c.isBlocked).map(cell => {
307
390
  const isInCurrentClue = this.isInClue(cell);
308
391
  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));
392
+ const isSpecial = this.specialCells.some(c => c.x === cell.x && c.y === cell.y);
393
+ return index.h(Cell, { isSpecial: isSpecial, onPointerDown: () => this.selectClueByXY(index$1.Vec2.from(cell)), isInCurrentClue: isInCurrentClue, isSelected: isSelected, data: cell });
394
+ }), this.specialBorders.map((b, index$1) => {
395
+ return index.h("div", { key: index$1, part: "special-border", class: {
396
+ 'top': Boolean(b.border & 0x1000),
397
+ 'right': Boolean(b.border & 0x0100),
398
+ 'bottom': Boolean(b.border & 0x0010),
399
+ 'left': Boolean(b.border & 0x0001),
400
+ }, style: {
401
+ "--x": `${b.x}`,
402
+ "--y": `${b.y}`
403
+ } });
404
+ })), index.h("div", { key: '24818d75c9ecf6df2f4e1044ab8d74e1e413f29e', part: "preview" }, "Tu bedzie podgl\u0105d: ", this.currentClueId));
311
405
  }
406
+ static get delegatesFocus() { return true; }
407
+ static get watchers() { return {
408
+ "data": [{
409
+ "watchData": 0
410
+ }]
411
+ }; }
312
412
  };
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;
413
+ function isLastCellInClue(clue, cell) {
414
+ return getClueLastCell(clue).eq(index$1.Vec2.from(cell));
415
+ }
416
+ function isFirstCellInWord(clue, cell) {
417
+ return index$1.Vec2.from(clue).eq(index$1.Vec2.from(cell));
418
+ }
419
+ function getClueLastCell(clue) {
420
+ return new index$1.Vec2(clue.x + (clue.orientation === 'horizontal' ? (clue.word.length - 1) : 0), clue.y + (clue.orientation === 'vertical' ? (clue.word.length - 1) : 0));
320
421
  }
321
422
  MBCrossword.style = mbCrosswordCss();
322
423
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-TyGpRn4d.js');
3
+ var index = require('./index-BlTGwvVC.js');
4
4
  var appGlobals = require('./app-globals-V2Kpy_OQ.js');
5
5
 
6
6
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -19,7 +19,7 @@ var patchBrowser = () => {
19
19
 
20
20
  patchBrowser().then(async (options) => {
21
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);
22
+ return index.bootstrapLazy([["mb-crossword.cjs",[[529,"mb-crossword",{"init":[4],"data":[16],"hWords":[32],"vWords":[32],"currentClueId":[32],"currentClue":[32],"isFocused":[32],"selectedCell":[32],"specialBorders":[32],"specialCells":[32],"boardWidth":[32],"boardHeight":[32],"cells":[32],"initGame":[64]},null,{"data":[{"watchData":0}]}]]]], options);
23
23
  });
24
24
 
25
25
  exports.setNonce = index.setNonce;
@@ -1,8 +1,13 @@
1
1
  import { h } from "@stencil/core";
2
- export function Cell({ data, isInCurrentClue, isSelected }) {
3
- return h("div", { part: "cell", class: {
2
+ export function Cell({ data, isInCurrentClue, isSelected, isSpecial, onPointerDown }) {
3
+ return h("div", { onPointerDown: onPointerDown, part: "cell", class: {
4
4
  "--blocked": data.isBlocked,
5
5
  '--in-current-clue': isInCurrentClue,
6
6
  '--selected': isSelected,
7
+ '--alt': !((data.x + data.y) % 2),
8
+ '--special': isSpecial
9
+ }, style: {
10
+ "--x": `${data.x}`,
11
+ "--y": `${data.y}`
7
12
  } }, h("div", { class: "_inner", style: { position: 'absolute', width: '100%' } }, data.value));
8
13
  }
@@ -1,6 +1,6 @@
1
1
  import { h } from "@stencil/core";
2
- export function Clue({ isCurrent, word, onPointerDown }) {
2
+ export function Clue({ isCurrent, word, onPointerDown, preview }) {
3
3
  return h("p", { onPointerDown: onPointerDown, part: "clue", class: {
4
4
  "--current": isCurrent
5
- } }, word.clue);
5
+ } }, word.clue, h("span", { class: "preview" }, preview));
6
6
  }