@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.
Files changed (36) 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 +159 -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 +107 -13
  10. package/dist/collection/components/crossword/mb-crossword.js +189 -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 +159 -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-34ea8cf1.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 +5 -3
  27. package/dist/types/components/crossword/mb-crossword.d.ts +18 -6
  28. package/dist/types/components/crossword/types.d.ts +21 -2
  29. package/dist/types/components.d.ts +9 -0
  30. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/grid/src/grid.d.ts +12 -0
  31. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/grid/vitest.config.d.ts +2 -0
  32. package/dist/types/roboczy/mb-puzzle/apps/crossword/.stencil/shared/vec2/src/vec2.d.ts +9 -2
  33. package/dist/types/utils/utils.d.ts +1 -0
  34. package/package.json +6 -1
  35. package/dist/mb-crossword/p-0i8AYf_G.js +0 -1
  36. 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],"showCluePreview":[4,"show-clue-preview"],"hWords":[32],"vWords":[32],"currentClueId":[32],"currentClue":[32],"isFocused":[32],"selectedCell":[32],"specialBorders":[32],"specialCells":[32],"labels":[32],"boardWidth":[32],"boardHeight":[32],"cells":[32],"initGame":[64],"checkAnswer":[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, showPreview }) {
7
7
  return index.h("p", { onPointerDown: onPointerDown, part: "clue", class: {
8
8
  "--current": isCurrent
9
- } }, word.clue);
9
+ } }, word.clue, showPreview && 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;border:none}[part=clues]{grid-area:clues;display:grid;grid-template-columns:1fr 1fr;gap:16px}[part=clues].oneList{grid-template-columns:1fr}[part=clue].--current{background:var(--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:var(--board-background, darkgoldenrod);--cell-border-width:2px;--cell-width-temp:calc((100cqw - var(--cell-border-width)) / var(--board-width, 10));--cell-width:var(--cell-width-temp);--cell-width:round(var(--cell-width-temp), 1px)}[part=cell]{display:block;color:var(--cell-color, #11138d);width:calc(var(--cell-width) - var(--cell-border-width));aspect-ratio:1;background:var(--cell-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(--cell-border-width) solid var(--cell-border-color, red)}[part=cell].--alt{background:var(--cell-background-alt, #999)}[part=cell].--in-current-clue{box-shadow:inset 0 0 2px 2px var(--cell-selected-background, lightblue)}[part=cell].--selected{background:var(--cell-selected-background, lightblue)}[part=cell].--special{background:var(--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(--cell-border-width))}[part=special-border].left,[part=special-border].right{width:var(--s-border);height:calc(var(--cell-width) - var(--cell-border-width));top:calc(var(--y, 0) * var(--cell-width) + var(--cell-border-width))}[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(--cell-border-width));height:var(--s-border);left:calc(var(--x, 0) * var(--cell-width) + var(--cell-border-width))}[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))}[part=label]{display:grid;place-content:center;position:absolute;container-type:size;top:calc(var(--y, 0) * var(--cell-width));left:calc(var(--x, 0) * var(--cell-width));width:calc(var(--cell-width) - var(--cell-border-width));aspect-ratio:1}[part=label] ._inner{position:absolute;top:0;left:0;right:0;bottom:0;display:grid;place-content:center;text-transform:uppercase;font-size:60cqh}`;
21
26
 
22
27
  const MBCrossword = class {
23
28
  constructor(hostRef) {
@@ -25,6 +30,8 @@ const MBCrossword = class {
25
30
  }
26
31
  init = true;
27
32
  data;
33
+ showCluePreview = true;
34
+ textInput;
28
35
  hWords = [];
29
36
  vWords = [];
30
37
  currentClueId = null;
@@ -32,6 +39,12 @@ const MBCrossword = class {
32
39
  isFocused = false;
33
40
  selectedCell = null;
34
41
  componentWillLoad() {
42
+ console.log('componentWillLoad', this.init, this.data);
43
+ if (this.init && this.data) {
44
+ this.initGame();
45
+ }
46
+ }
47
+ watchData() {
35
48
  if (this.init && this.data) {
36
49
  this.initGame();
37
50
  }
@@ -43,6 +56,7 @@ const MBCrossword = class {
43
56
  ];
44
57
  }
45
58
  async initGame(data = this.data) {
59
+ console.log('initGame');
46
60
  if (!data.words) {
47
61
  throw new Error('Words definition missing');
48
62
  }
@@ -60,8 +74,22 @@ const MBCrossword = class {
60
74
  this.vWords = [...this.vWords, w];
61
75
  }
62
76
  });
77
+ this.specialBorders = data.specialBorders ?? [];
78
+ this.specialCells = data.specialCells ?? [];
79
+ this.labels = data.labels ?? [];
63
80
  this.buildBoard();
64
81
  }
82
+ async checkAnswer() {
83
+ const cells = this.cells.filter(c => !c.isBlocked);
84
+ console.log(cells);
85
+ cells.forEach(c => {
86
+ console.log(`${c.value} === ${c.answer}`, `${c.x},${c.y}`, c.value === c.answer);
87
+ });
88
+ return cells.every(c => c.value === c.answer);
89
+ }
90
+ specialBorders = [];
91
+ specialCells = [];
92
+ labels = [];
65
93
  boardWidth = 0;
66
94
  boardHeight = 0;
67
95
  cells = [];
@@ -96,6 +124,7 @@ const MBCrossword = class {
96
124
  const v = index$1.Vec2.from(w);
97
125
  const cellIndex = index$1.indexFromXY(new index$1.Vec2(v.x + i, v.y), boardWidth);
98
126
  cells[cellIndex].isBlocked = false;
127
+ cells[cellIndex].answer = w.word[i];
99
128
  }
100
129
  }
101
130
  if (w.orientation === 'vertical') {
@@ -103,6 +132,7 @@ const MBCrossword = class {
103
132
  const v = index$1.Vec2.from(w);
104
133
  const cellIndex = index$1.indexFromXY(new index$1.Vec2(v.x, v.y + i), boardWidth);
105
134
  cells[cellIndex].isBlocked = false;
135
+ cells[cellIndex].answer = w.word[i];
106
136
  }
107
137
  }
108
138
  });
@@ -110,6 +140,9 @@ const MBCrossword = class {
110
140
  this.boardWidth = boardWidth;
111
141
  this.boardHeight = boardHeight;
112
142
  }
143
+ getClueById(id) {
144
+ return this.allWords.find(c => c.id === id) ?? null;
145
+ }
113
146
  isInClue(xy, clue = this.currentClue) {
114
147
  if (clue === null)
115
148
  return false;
@@ -166,25 +199,58 @@ const MBCrossword = class {
166
199
  this.selectNextCell();
167
200
  index.forceUpdate(this);
168
201
  }
202
+ backspace() {
203
+ if (!this.selectedCell)
204
+ return;
205
+ if (this.selectedCell.value) {
206
+ this.selectedCell.value = '';
207
+ this.selectPrevCell();
208
+ }
209
+ else {
210
+ this.selectPrevCell();
211
+ this.selectedCell.value = '';
212
+ }
213
+ index.forceUpdate(this);
214
+ }
169
215
  selectNextCell() {
170
216
  if (!this.selectedCell || !this.currentClue)
171
217
  return;
172
218
  const currentOrientation = this.currentClue.orientation;
173
- if (isLastCellInWord(this.currentClue, this.selectedCell)) {
219
+ if (isLastCellInClue(this.currentClue, this.selectedCell)) {
174
220
  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);
221
+ const clue = this.getClueById(nextClueId);
222
+ if (clue) {
223
+ this.selectClueByXY(index$1.Vec2.from(clue));
224
+ return;
180
225
  }
181
226
  return;
182
227
  }
183
228
  if (currentOrientation === 'horizontal') {
184
- this.selectCellByXY(new index$1.Vec2(this.selectedCell.x + 1, this.selectedCell.y));
229
+ this.selectClueByXY(new index$1.Vec2(this.selectedCell.x + 1, this.selectedCell.y));
230
+ }
231
+ if (currentOrientation === 'vertical') {
232
+ this.selectClueByXY(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y + 1));
233
+ }
234
+ }
235
+ selectPrevCell() {
236
+ if (!this.selectedCell || !this.currentClue)
237
+ return;
238
+ const currentOrientation = this.currentClue.orientation;
239
+ if (isFirstCellInWord(this.currentClue, this.selectedCell)) {
240
+ const prevClueId = this.getPrevClueId();
241
+ const clue = this.getClueById(prevClueId);
242
+ if (clue) {
243
+ const cell = getClueLastCell(clue);
244
+ console.log(cell);
245
+ this.selectClueByXY(cell);
246
+ return;
247
+ }
248
+ }
249
+ if (currentOrientation === 'horizontal') {
250
+ this.selectClueByXY(new index$1.Vec2(this.selectedCell.x - 1, this.selectedCell.y));
185
251
  }
186
252
  if (currentOrientation === 'vertical') {
187
- this.selectCellByXY(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y + 1));
253
+ this.selectClueByXY(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y - 1));
188
254
  }
189
255
  }
190
256
  onFocusin() {
@@ -192,6 +258,7 @@ const MBCrossword = class {
192
258
  if (!this.currentClueId) {
193
259
  this.currentClueId = this.allWords[0]?.id ?? null;
194
260
  }
261
+ this.textInput.focus();
195
262
  }
196
263
  onFocusOut() {
197
264
  this.isFocused = false;
@@ -255,8 +322,27 @@ const MBCrossword = class {
255
322
  if (!clues.length) {
256
323
  return;
257
324
  }
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 });
325
+ if (this.selectedCell && clues.length === 2 && v.eq(index$1.Vec2.from(this.selectedCell))) {
326
+ const betterClue = clues.find(c => c.orientation !== this.currentClue?.orientation);
327
+ this.selectClue(betterClue?.id ?? clues[0].id, { row: v.y, col: v.x });
328
+ }
329
+ else {
330
+ const betterClue = clues.find(c => c.orientation === this.currentClue?.orientation);
331
+ this.selectClue(betterClue?.id ?? clues[0].id, { row: v.y, col: v.x });
332
+ }
333
+ }
334
+ getCluePreview(clue) {
335
+ if (!clue)
336
+ return '_';
337
+ const letters = Array(clue.word.length).fill('_');
338
+ for (let i = 0; i < clue.word.length; i++) {
339
+ 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));
340
+ const cell = this.cells[index$1.indexFromXY(pointer, this.boardWidth)];
341
+ if (cell.value) {
342
+ letters[i] = cell.value;
343
+ }
344
+ }
345
+ return letters.join('');
260
346
  }
261
347
  onKeyPress(event) {
262
348
  console.log(event);
@@ -267,9 +353,6 @@ const MBCrossword = class {
267
353
  this.selectClue(nextClue);
268
354
  }
269
355
  }
270
- if (index$1.isKeyboardEventLetter(event)) {
271
- this.inputLetter(event.key.toLowerCase()[0]);
272
- }
273
356
  if (this.selectedCell) {
274
357
  switch (event.key) {
275
358
  case 'ArrowLeft':
@@ -288,35 +371,73 @@ const MBCrossword = class {
288
371
  this.selectClueByXY(this.findNonblockedCell(new index$1.Vec2(this.selectedCell.x, this.selectedCell.y), new index$1.Vec2(0, 1)));
289
372
  event.preventDefault();
290
373
  return;
374
+ case 'Backspace':
375
+ console.log('BACKSPACE!');
376
+ this.backspace();
291
377
  }
292
378
  }
293
379
  }
380
+ onInput(event) {
381
+ if (index$1.isInputEventLetter(event)) {
382
+ this.inputLetter(event.data.toLowerCase()[0]);
383
+ }
384
+ this.textInput.value = '';
385
+ }
294
386
  render() {
295
- return index.h("div", { key: 'e298ac6f3a1d95bc41c4854b39600f8ac7f1696d', part: "main", class: {
387
+ const hasVWords = Boolean(this.vWords.length);
388
+ const hasHWords = Boolean(this.hWords.length);
389
+ const twoLists = hasHWords && hasVWords;
390
+ return index.h("div", { key: '87d88806305c6102eeb76c3984d4b9c2ad2d9759', part: "main", class: {
296
391
  "--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 => {
392
+ }, onFocusin: this.onFocusin.bind(this), onFocusout: this.onFocusOut.bind(this) }, index.h("input", { key: '49cdb053a4d2c4ad2c7eb881488b18c68e31fe65', type: "text", class: "dummy", ref: (el) => this.textInput = el, onKeyDown: this.onKeyPress.bind(this), onInput: this.onInput.bind(this) }), index.h("div", { key: '0ca71a907f70e17a6d2d10bff9462bd0b2284007', part: "clues", class: {
393
+ twoLists, oneList: !twoLists
394
+ } }, hasHWords ? index.h("div", { part: "clue-list" }, this.hWords.map(w => {
298
395
  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 => {
396
+ return index.h(Clue, { showPreview: this.showCluePreview, preview: this.getCluePreview(w), word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
397
+ })) : '', hasVWords ? index.h("div", { part: "clue-list" }, this.vWords.map(w => {
301
398
  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 => {
399
+ return index.h(Clue, { showPreview: this.showCluePreview, preview: this.getCluePreview(w), word: w, isCurrent: isCurrent, onPointerDown: () => this.selectClue(w.id) });
400
+ })) : ''), index.h("div", { key: 'ea16dca25fe7884d25f9748f98740ad83e25293e', part: "board", style: {
401
+ '--board-width': `${this.boardWidth}`,
402
+ 'grid-template-columns': `repeat(${this.boardWidth}, 1fr)`,
403
+ aspectRatio: `${this.boardWidth / this.boardHeight}`
404
+ } }, this.cells.filter(c => !c.isBlocked).map(cell => {
307
405
  const isInCurrentClue = this.isInClue(cell);
308
406
  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));
407
+ const isSpecial = this.specialCells.some(c => c.x === cell.x && c.y === cell.y);
408
+ return index.h(Cell, { isSpecial: isSpecial, onPointerDown: () => this.selectClueByXY(index$1.Vec2.from(cell)), isInCurrentClue: isInCurrentClue, isSelected: isSelected, data: cell });
409
+ }), this.specialBorders.map((b, index$1) => {
410
+ return index.h("div", { key: index$1, part: "special-border", class: {
411
+ 'top': Boolean(b.border & 0x1000),
412
+ 'right': Boolean(b.border & 0x0100),
413
+ 'bottom': Boolean(b.border & 0x0010),
414
+ 'left': Boolean(b.border & 0x0001),
415
+ }, style: {
416
+ "--x": `${b.x}`,
417
+ "--y": `${b.y}`
418
+ } });
419
+ }), this.labels.map((label) => {
420
+ return index.h("div", { part: "label", style: {
421
+ "--x": `${label.x}`,
422
+ "--y": `${label.y}`
423
+ }, onPointerDown: () => this.selectClue(label.clueId) }, index.h("div", { class: "_inner" }, label.text));
424
+ })), index.h("div", { key: 'd391413e7be3dee148f2f5e6d8fbf22742278a0c', part: "preview" }, "Tu bedzie podgl\u0105d: ", this.currentClueId));
311
425
  }
426
+ static get delegatesFocus() { return true; }
427
+ static get watchers() { return {
428
+ "data": [{
429
+ "watchData": 0
430
+ }]
431
+ }; }
312
432
  };
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;
433
+ function isLastCellInClue(clue, cell) {
434
+ return getClueLastCell(clue).eq(index$1.Vec2.from(cell));
435
+ }
436
+ function isFirstCellInWord(clue, cell) {
437
+ return index$1.Vec2.from(clue).eq(index$1.Vec2.from(cell));
438
+ }
439
+ function getClueLastCell(clue) {
440
+ 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
441
  }
321
442
  MBCrossword.style = mbCrosswordCss();
322
443
 
@@ -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],"showCluePreview":[4,"show-clue-preview"],"hWords":[32],"vWords":[32],"currentClueId":[32],"currentClue":[32],"isFocused":[32],"selectedCell":[32],"specialBorders":[32],"specialCells":[32],"labels":[32],"boardWidth":[32],"boardHeight":[32],"cells":[32],"initGame":[64],"checkAnswer":[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, showPreview }) {
3
3
  return h("p", { onPointerDown: onPointerDown, part: "clue", class: {
4
4
  "--current": isCurrent
5
- } }, word.clue);
5
+ } }, word.clue, showPreview && h("span", { class: "preview" }, preview));
6
6
  }