@selimssevgi/cube-design-angular 0.0.0-stage → 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/CHANGELOG.md +23 -0
- package/README.md +423 -2
- package/fesm2022/selimssevgi-cube-design-angular.mjs +2116 -0
- package/fesm2022/selimssevgi-cube-design-angular.mjs.map +1 -0
- package/package.json +35 -3
- package/tokens/dark.css +38 -0
- package/tokens/light.css +38 -0
- package/types/selimssevgi-cube-design-angular.d.ts +750 -0
|
@@ -0,0 +1,2116 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, InjectionToken, TemplateRef, afterNextRender, computed, contentChild, effect, inject, input, output, signal, untracked, viewChild } from "@angular/core";
|
|
3
|
+
import { NgTemplateOutlet } from "@angular/common";
|
|
4
|
+
function sizeFor(count) {
|
|
5
|
+
let s = 1;
|
|
6
|
+
while (s * s * s < count && s < 7) s++;
|
|
7
|
+
return s;
|
|
8
|
+
}
|
|
9
|
+
const C30 = Math.cos(Math.PI / 6);
|
|
10
|
+
function poly(pts, k) {
|
|
11
|
+
const cx = pts.reduce((a, q) => a + q[0], 0) / pts.length;
|
|
12
|
+
const cy = pts.reduce((a, q) => a + q[1], 0) / pts.length;
|
|
13
|
+
return pts.map(([x, y]) => `${(cx + (x - cx) * k).toFixed(1)},${(cy + (y - cy) * k).toFixed(1)}`).join(" ");
|
|
14
|
+
}
|
|
15
|
+
function squares(n, s, shift) {
|
|
16
|
+
const ox = n * s * C30;
|
|
17
|
+
const oy = n * s;
|
|
18
|
+
const p = (x, y, z) => [shift[0] + ox + (x - y) * C30 * s, shift[1] + oy + (x + y) * .5 * s - z * s];
|
|
19
|
+
const out = [];
|
|
20
|
+
for (let a = 0; a < n; a++) for (let b = n - 1; b >= 0; b--) out.push({
|
|
21
|
+
face: "left",
|
|
22
|
+
pts: [
|
|
23
|
+
p(a, n, b + 1),
|
|
24
|
+
p(a + 1, n, b + 1),
|
|
25
|
+
p(a + 1, n, b),
|
|
26
|
+
p(a, n, b)
|
|
27
|
+
]
|
|
28
|
+
});
|
|
29
|
+
for (let a = 0; a < n; a++) for (let b = n - 1; b >= 0; b--) out.push({
|
|
30
|
+
face: "right",
|
|
31
|
+
pts: [
|
|
32
|
+
p(n, a, b + 1),
|
|
33
|
+
p(n, a + 1, b + 1),
|
|
34
|
+
p(n, a + 1, b),
|
|
35
|
+
p(n, a, b)
|
|
36
|
+
]
|
|
37
|
+
});
|
|
38
|
+
for (let a = 0; a < n; a++) for (let b = 0; b < n; b++) out.push({
|
|
39
|
+
face: "top",
|
|
40
|
+
pts: [
|
|
41
|
+
p(a, b, n),
|
|
42
|
+
p(a + 1, b, n),
|
|
43
|
+
p(a + 1, b + 1, n),
|
|
44
|
+
p(a, b + 1, n)
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
function drawCube(count, colours, width, options = {}) {
|
|
50
|
+
const n = sizeFor(Math.max(1, count));
|
|
51
|
+
const hinted = !!options.hint && count < 9;
|
|
52
|
+
const big = hinted ? n + 1 : n;
|
|
53
|
+
const s = width / (2 * big * C30);
|
|
54
|
+
const hint = hinted ? squares(big, s, [0, 0]).map((q) => poly(q.pts, .86)) : [];
|
|
55
|
+
const shift = hinted ? [(big - n) * s * C30, (big - n) * s * 2] : [0, 0];
|
|
56
|
+
const k = colours.length ? (options.rot ?? 0) % colours.length : 0;
|
|
57
|
+
const turned = colours.slice(k).concat(colours.slice(0, k));
|
|
58
|
+
const stickers = squares(n, s, shift).map((q, i) => ({
|
|
59
|
+
face: q.face,
|
|
60
|
+
outer: poly(q.pts, 1),
|
|
61
|
+
inner: poly(q.pts, .86),
|
|
62
|
+
colour: options.whole ? colours[0] ?? null : turned[i] ?? null
|
|
63
|
+
}));
|
|
64
|
+
const height = 2 * big * s;
|
|
65
|
+
return {
|
|
66
|
+
width,
|
|
67
|
+
height: Math.round(height),
|
|
68
|
+
viewBox: `-2 -2 ${(width + 4).toFixed(1)} ${(height + 4).toFixed(1)}`,
|
|
69
|
+
hint,
|
|
70
|
+
stickers
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
var CubePicture = class CubePicture {
|
|
74
|
+
count = input(1, ...ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []);
|
|
75
|
+
colours = input([], ...ngDevMode ? [{ debugName: "colours" }] : /* istanbul ignore next */ []);
|
|
76
|
+
width = input(64, ...ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []);
|
|
77
|
+
hint = input(false, ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
|
|
78
|
+
whole = input(false, ...ngDevMode ? [{ debugName: "whole" }] : /* istanbul ignore next */ []);
|
|
79
|
+
rot = input(0, ...ngDevMode ? [{ debugName: "rot" }] : /* istanbul ignore next */ []);
|
|
80
|
+
drawing = computed(() => drawCube(this.count(), this.colours(), this.width(), {
|
|
81
|
+
hint: this.hint(),
|
|
82
|
+
whole: this.whole(),
|
|
83
|
+
rot: this.rot()
|
|
84
|
+
}), ...ngDevMode ? [{ debugName: "drawing" }] : /* istanbul ignore next */ []);
|
|
85
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
86
|
+
minVersion: "12.0.0",
|
|
87
|
+
version: "22.2.4",
|
|
88
|
+
ngImport: i0,
|
|
89
|
+
type: CubePicture,
|
|
90
|
+
deps: [],
|
|
91
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
92
|
+
});
|
|
93
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
94
|
+
minVersion: "17.0.0",
|
|
95
|
+
version: "22.2.4",
|
|
96
|
+
type: CubePicture,
|
|
97
|
+
isStandalone: true,
|
|
98
|
+
selector: "cube-picture",
|
|
99
|
+
inputs: {
|
|
100
|
+
count: {
|
|
101
|
+
classPropertyName: "count",
|
|
102
|
+
publicName: "count",
|
|
103
|
+
isSignal: true,
|
|
104
|
+
isRequired: false,
|
|
105
|
+
transformFunction: null
|
|
106
|
+
},
|
|
107
|
+
colours: {
|
|
108
|
+
classPropertyName: "colours",
|
|
109
|
+
publicName: "colours",
|
|
110
|
+
isSignal: true,
|
|
111
|
+
isRequired: false,
|
|
112
|
+
transformFunction: null
|
|
113
|
+
},
|
|
114
|
+
width: {
|
|
115
|
+
classPropertyName: "width",
|
|
116
|
+
publicName: "width",
|
|
117
|
+
isSignal: true,
|
|
118
|
+
isRequired: false,
|
|
119
|
+
transformFunction: null
|
|
120
|
+
},
|
|
121
|
+
hint: {
|
|
122
|
+
classPropertyName: "hint",
|
|
123
|
+
publicName: "hint",
|
|
124
|
+
isSignal: true,
|
|
125
|
+
isRequired: false,
|
|
126
|
+
transformFunction: null
|
|
127
|
+
},
|
|
128
|
+
whole: {
|
|
129
|
+
classPropertyName: "whole",
|
|
130
|
+
publicName: "whole",
|
|
131
|
+
isSignal: true,
|
|
132
|
+
isRequired: false,
|
|
133
|
+
transformFunction: null
|
|
134
|
+
},
|
|
135
|
+
rot: {
|
|
136
|
+
classPropertyName: "rot",
|
|
137
|
+
publicName: "rot",
|
|
138
|
+
isSignal: true,
|
|
139
|
+
isRequired: false,
|
|
140
|
+
transformFunction: null
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
ngImport: i0,
|
|
144
|
+
template: `
|
|
145
|
+
@let d = drawing();
|
|
146
|
+
<svg
|
|
147
|
+
[attr.viewBox]="d.viewBox"
|
|
148
|
+
[attr.width]="d.width"
|
|
149
|
+
[attr.height]="d.height"
|
|
150
|
+
aria-hidden="true"
|
|
151
|
+
>
|
|
152
|
+
@for (q of d.hint; track $index) {
|
|
153
|
+
<polygon class="hint" [attr.points]="q" />
|
|
154
|
+
}
|
|
155
|
+
@for (q of d.stickers; track $index) {
|
|
156
|
+
<polygon [attr.points]="q.outer" [attr.class]="'side ' + q.face" />
|
|
157
|
+
}
|
|
158
|
+
@for (q of d.stickers; track $index) {
|
|
159
|
+
<polygon
|
|
160
|
+
[attr.points]="q.inner"
|
|
161
|
+
[attr.class]="q.colour ? 'sticker' : 'sticker unknown'"
|
|
162
|
+
[attr.fill]="q.colour"
|
|
163
|
+
/>
|
|
164
|
+
}
|
|
165
|
+
</svg>
|
|
166
|
+
`,
|
|
167
|
+
isInline: true,
|
|
168
|
+
styles: [":host{display:inline-block;line-height:0}svg{overflow:visible}.hint{fill:none;stroke:var(--cube-hint, #87938c);stroke-width:1;stroke-dasharray:3 3;opacity:var(--cube-hint-opacity, .5)}.side{stroke:var(--cube-edge, #cdd8d0);stroke-width:var(--cube-edge-width, .6)}.top{fill:var(--cube-top, #f9fbf8)}.left{fill:var(--cube-left, #e9eee9)}.right{fill:var(--cube-right, #dfe6e0)}.sticker{stroke:var(--cube-sticker-edge, rgba(31, 45, 39, .28));stroke-width:1}.unknown{fill:var(--cube-unknown, #e3e7e1);stroke:var(--cube-unknown-edge, none)}\n"],
|
|
169
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
173
|
+
minVersion: "12.0.0",
|
|
174
|
+
version: "22.2.4",
|
|
175
|
+
ngImport: i0,
|
|
176
|
+
type: CubePicture,
|
|
177
|
+
decorators: [{
|
|
178
|
+
type: Component,
|
|
179
|
+
args: [{
|
|
180
|
+
selector: "cube-picture",
|
|
181
|
+
template: `
|
|
182
|
+
@let d = drawing();
|
|
183
|
+
<svg
|
|
184
|
+
[attr.viewBox]="d.viewBox"
|
|
185
|
+
[attr.width]="d.width"
|
|
186
|
+
[attr.height]="d.height"
|
|
187
|
+
aria-hidden="true"
|
|
188
|
+
>
|
|
189
|
+
@for (q of d.hint; track $index) {
|
|
190
|
+
<polygon class="hint" [attr.points]="q" />
|
|
191
|
+
}
|
|
192
|
+
@for (q of d.stickers; track $index) {
|
|
193
|
+
<polygon [attr.points]="q.outer" [attr.class]="'side ' + q.face" />
|
|
194
|
+
}
|
|
195
|
+
@for (q of d.stickers; track $index) {
|
|
196
|
+
<polygon
|
|
197
|
+
[attr.points]="q.inner"
|
|
198
|
+
[attr.class]="q.colour ? 'sticker' : 'sticker unknown'"
|
|
199
|
+
[attr.fill]="q.colour"
|
|
200
|
+
/>
|
|
201
|
+
}
|
|
202
|
+
</svg>
|
|
203
|
+
`,
|
|
204
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
205
|
+
styles: [":host{display:inline-block;line-height:0}svg{overflow:visible}.hint{fill:none;stroke:var(--cube-hint, #87938c);stroke-width:1;stroke-dasharray:3 3;opacity:var(--cube-hint-opacity, .5)}.side{stroke:var(--cube-edge, #cdd8d0);stroke-width:var(--cube-edge-width, .6)}.top{fill:var(--cube-top, #f9fbf8)}.left{fill:var(--cube-left, #e9eee9)}.right{fill:var(--cube-right, #dfe6e0)}.sticker{stroke:var(--cube-sticker-edge, rgba(31, 45, 39, .28));stroke-width:1}.unknown{fill:var(--cube-unknown, #e3e7e1);stroke:var(--cube-unknown-edge, none)}\n"]
|
|
206
|
+
}]
|
|
207
|
+
}],
|
|
208
|
+
propDecorators: {
|
|
209
|
+
count: [{
|
|
210
|
+
type: i0.Input,
|
|
211
|
+
args: [{
|
|
212
|
+
isSignal: true,
|
|
213
|
+
alias: "count",
|
|
214
|
+
required: false
|
|
215
|
+
}]
|
|
216
|
+
}],
|
|
217
|
+
colours: [{
|
|
218
|
+
type: i0.Input,
|
|
219
|
+
args: [{
|
|
220
|
+
isSignal: true,
|
|
221
|
+
alias: "colours",
|
|
222
|
+
required: false
|
|
223
|
+
}]
|
|
224
|
+
}],
|
|
225
|
+
width: [{
|
|
226
|
+
type: i0.Input,
|
|
227
|
+
args: [{
|
|
228
|
+
isSignal: true,
|
|
229
|
+
alias: "width",
|
|
230
|
+
required: false
|
|
231
|
+
}]
|
|
232
|
+
}],
|
|
233
|
+
hint: [{
|
|
234
|
+
type: i0.Input,
|
|
235
|
+
args: [{
|
|
236
|
+
isSignal: true,
|
|
237
|
+
alias: "hint",
|
|
238
|
+
required: false
|
|
239
|
+
}]
|
|
240
|
+
}],
|
|
241
|
+
whole: [{
|
|
242
|
+
type: i0.Input,
|
|
243
|
+
args: [{
|
|
244
|
+
isSignal: true,
|
|
245
|
+
alias: "whole",
|
|
246
|
+
required: false
|
|
247
|
+
}]
|
|
248
|
+
}],
|
|
249
|
+
rot: [{
|
|
250
|
+
type: i0.Input,
|
|
251
|
+
args: [{
|
|
252
|
+
isSignal: true,
|
|
253
|
+
alias: "rot",
|
|
254
|
+
required: false
|
|
255
|
+
}]
|
|
256
|
+
}]
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
const CUBE_HOLD_MS = 520;
|
|
260
|
+
const CUBE_HOLD_SLOP = 10;
|
|
261
|
+
var CubeHold = class CubeHold {
|
|
262
|
+
cubeHoldDisabled = input(false, ...ngDevMode ? [{ debugName: "cubeHoldDisabled" }] : /* istanbul ignore next */ []);
|
|
263
|
+
cubeHoldMs = input(520, ...ngDevMode ? [{ debugName: "cubeHoldMs" }] : /* istanbul ignore next */ []);
|
|
264
|
+
cubeHoldSlop = input(10, ...ngDevMode ? [{ debugName: "cubeHoldSlop" }] : /* istanbul ignore next */ []);
|
|
265
|
+
cubeHoldBuzz = input(true, ...ngDevMode ? [{ debugName: "cubeHoldBuzz" }] : /* istanbul ignore next */ []);
|
|
266
|
+
cubeHeld = output();
|
|
267
|
+
element = inject(ElementRef).nativeElement;
|
|
268
|
+
timer;
|
|
269
|
+
start = null;
|
|
270
|
+
pointers = /* @__PURE__ */ new Set();
|
|
271
|
+
pressFired = false;
|
|
272
|
+
swallow = false;
|
|
273
|
+
constructor() {
|
|
274
|
+
const swallow = (e) => {
|
|
275
|
+
if (!this.swallow) return;
|
|
276
|
+
this.swallow = false;
|
|
277
|
+
e.preventDefault();
|
|
278
|
+
e.stopImmediatePropagation();
|
|
279
|
+
};
|
|
280
|
+
this.element.addEventListener("click", swallow, true);
|
|
281
|
+
inject(DestroyRef).onDestroy(() => {
|
|
282
|
+
clearTimeout(this.timer);
|
|
283
|
+
this.element.removeEventListener("click", swallow, true);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
press(e) {
|
|
287
|
+
this.pointers.add(e.pointerId);
|
|
288
|
+
this.cancel();
|
|
289
|
+
this.pressFired = false;
|
|
290
|
+
this.swallow = false;
|
|
291
|
+
if (this.cubeHoldDisabled() || this.pointers.size > 1 || e.button > 0) return;
|
|
292
|
+
this.start = {
|
|
293
|
+
x: e.clientX,
|
|
294
|
+
y: e.clientY
|
|
295
|
+
};
|
|
296
|
+
this.timer = setTimeout(() => this.fire("press", e), this.cubeHoldMs());
|
|
297
|
+
}
|
|
298
|
+
moved(e) {
|
|
299
|
+
if (!this.start) return;
|
|
300
|
+
if (Math.hypot(e.clientX - this.start.x, e.clientY - this.start.y) > this.cubeHoldSlop()) this.cancel();
|
|
301
|
+
}
|
|
302
|
+
lift(e) {
|
|
303
|
+
this.pointers.delete(e.pointerId);
|
|
304
|
+
this.cancel();
|
|
305
|
+
}
|
|
306
|
+
menu(e) {
|
|
307
|
+
if (this.cubeHoldDisabled()) return;
|
|
308
|
+
e.preventDefault();
|
|
309
|
+
if (this.pressFired) return;
|
|
310
|
+
this.fire("menu", e);
|
|
311
|
+
}
|
|
312
|
+
fire(via, event) {
|
|
313
|
+
this.cancel();
|
|
314
|
+
if (this.cubeHoldDisabled()) return;
|
|
315
|
+
this.pressFired = via === "press";
|
|
316
|
+
this.swallow = true;
|
|
317
|
+
if (this.cubeHoldBuzz()) globalThis.navigator?.vibrate?.(12);
|
|
318
|
+
this.cubeHeld.emit({
|
|
319
|
+
via,
|
|
320
|
+
element: this.element,
|
|
321
|
+
event
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
cancel() {
|
|
325
|
+
clearTimeout(this.timer);
|
|
326
|
+
this.timer = void 0;
|
|
327
|
+
this.start = null;
|
|
328
|
+
}
|
|
329
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
330
|
+
minVersion: "12.0.0",
|
|
331
|
+
version: "22.2.4",
|
|
332
|
+
ngImport: i0,
|
|
333
|
+
type: CubeHold,
|
|
334
|
+
deps: [],
|
|
335
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
336
|
+
});
|
|
337
|
+
static ɵdir = i0.ɵɵngDeclareDirective({
|
|
338
|
+
minVersion: "17.1.0",
|
|
339
|
+
version: "22.2.4",
|
|
340
|
+
type: CubeHold,
|
|
341
|
+
isStandalone: true,
|
|
342
|
+
selector: "[cubeHold]",
|
|
343
|
+
inputs: {
|
|
344
|
+
cubeHoldDisabled: {
|
|
345
|
+
classPropertyName: "cubeHoldDisabled",
|
|
346
|
+
publicName: "cubeHoldDisabled",
|
|
347
|
+
isSignal: true,
|
|
348
|
+
isRequired: false,
|
|
349
|
+
transformFunction: null
|
|
350
|
+
},
|
|
351
|
+
cubeHoldMs: {
|
|
352
|
+
classPropertyName: "cubeHoldMs",
|
|
353
|
+
publicName: "cubeHoldMs",
|
|
354
|
+
isSignal: true,
|
|
355
|
+
isRequired: false,
|
|
356
|
+
transformFunction: null
|
|
357
|
+
},
|
|
358
|
+
cubeHoldSlop: {
|
|
359
|
+
classPropertyName: "cubeHoldSlop",
|
|
360
|
+
publicName: "cubeHoldSlop",
|
|
361
|
+
isSignal: true,
|
|
362
|
+
isRequired: false,
|
|
363
|
+
transformFunction: null
|
|
364
|
+
},
|
|
365
|
+
cubeHoldBuzz: {
|
|
366
|
+
classPropertyName: "cubeHoldBuzz",
|
|
367
|
+
publicName: "cubeHoldBuzz",
|
|
368
|
+
isSignal: true,
|
|
369
|
+
isRequired: false,
|
|
370
|
+
transformFunction: null
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
outputs: { cubeHeld: "cubeHeld" },
|
|
374
|
+
host: {
|
|
375
|
+
listeners: {
|
|
376
|
+
"pointerdown": "press($event)",
|
|
377
|
+
"pointermove": "moved($event)",
|
|
378
|
+
"pointerup": "lift($event)",
|
|
379
|
+
"pointercancel": "lift($event)",
|
|
380
|
+
"pointerleave": "lift($event)",
|
|
381
|
+
"contextmenu": "menu($event)",
|
|
382
|
+
"keydown": "pressFired = false; swallow = false"
|
|
383
|
+
},
|
|
384
|
+
properties: {
|
|
385
|
+
"style.user-select": "cubeHoldDisabled() ? null : \"none\"",
|
|
386
|
+
"style.-webkit-user-select": "cubeHoldDisabled() ? null : \"none\"",
|
|
387
|
+
"style.-webkit-touch-callout": "cubeHoldDisabled() ? null : \"none\""
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
ngImport: i0
|
|
391
|
+
});
|
|
392
|
+
};
|
|
393
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
394
|
+
minVersion: "12.0.0",
|
|
395
|
+
version: "22.2.4",
|
|
396
|
+
ngImport: i0,
|
|
397
|
+
type: CubeHold,
|
|
398
|
+
decorators: [{
|
|
399
|
+
type: Directive,
|
|
400
|
+
args: [{
|
|
401
|
+
selector: "[cubeHold]",
|
|
402
|
+
host: {
|
|
403
|
+
"[style.user-select]": "cubeHoldDisabled() ? null : \"none\"",
|
|
404
|
+
"[style.-webkit-user-select]": "cubeHoldDisabled() ? null : \"none\"",
|
|
405
|
+
"[style.-webkit-touch-callout]": "cubeHoldDisabled() ? null : \"none\"",
|
|
406
|
+
"(pointerdown)": "press($event)",
|
|
407
|
+
"(pointermove)": "moved($event)",
|
|
408
|
+
"(pointerup)": "lift($event)",
|
|
409
|
+
"(pointercancel)": "lift($event)",
|
|
410
|
+
"(pointerleave)": "lift($event)",
|
|
411
|
+
"(contextmenu)": "menu($event)",
|
|
412
|
+
"(keydown)": "pressFired = false; swallow = false"
|
|
413
|
+
}
|
|
414
|
+
}]
|
|
415
|
+
}],
|
|
416
|
+
ctorParameters: () => [],
|
|
417
|
+
propDecorators: {
|
|
418
|
+
cubeHoldDisabled: [{
|
|
419
|
+
type: i0.Input,
|
|
420
|
+
args: [{
|
|
421
|
+
isSignal: true,
|
|
422
|
+
alias: "cubeHoldDisabled",
|
|
423
|
+
required: false
|
|
424
|
+
}]
|
|
425
|
+
}],
|
|
426
|
+
cubeHoldMs: [{
|
|
427
|
+
type: i0.Input,
|
|
428
|
+
args: [{
|
|
429
|
+
isSignal: true,
|
|
430
|
+
alias: "cubeHoldMs",
|
|
431
|
+
required: false
|
|
432
|
+
}]
|
|
433
|
+
}],
|
|
434
|
+
cubeHoldSlop: [{
|
|
435
|
+
type: i0.Input,
|
|
436
|
+
args: [{
|
|
437
|
+
isSignal: true,
|
|
438
|
+
alias: "cubeHoldSlop",
|
|
439
|
+
required: false
|
|
440
|
+
}]
|
|
441
|
+
}],
|
|
442
|
+
cubeHoldBuzz: [{
|
|
443
|
+
type: i0.Input,
|
|
444
|
+
args: [{
|
|
445
|
+
isSignal: true,
|
|
446
|
+
alias: "cubeHoldBuzz",
|
|
447
|
+
required: false
|
|
448
|
+
}]
|
|
449
|
+
}],
|
|
450
|
+
cubeHeld: [{
|
|
451
|
+
type: i0.Output,
|
|
452
|
+
args: ["cubeHeld"]
|
|
453
|
+
}]
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
const CUBE_ICON_NAMES = [
|
|
457
|
+
"names",
|
|
458
|
+
"name",
|
|
459
|
+
"change",
|
|
460
|
+
"move",
|
|
461
|
+
"place",
|
|
462
|
+
"whose",
|
|
463
|
+
"library",
|
|
464
|
+
"mine",
|
|
465
|
+
"shown",
|
|
466
|
+
"hidden",
|
|
467
|
+
"view",
|
|
468
|
+
"sort",
|
|
469
|
+
"kept",
|
|
470
|
+
"face",
|
|
471
|
+
"added",
|
|
472
|
+
"up",
|
|
473
|
+
"down",
|
|
474
|
+
"plus",
|
|
475
|
+
"square",
|
|
476
|
+
"one",
|
|
477
|
+
"two",
|
|
478
|
+
"three",
|
|
479
|
+
"four",
|
|
480
|
+
"grid-4x5",
|
|
481
|
+
"grid-3x6"
|
|
482
|
+
];
|
|
483
|
+
const SHAPES = {
|
|
484
|
+
square: {
|
|
485
|
+
cols: 3,
|
|
486
|
+
rows: 3
|
|
487
|
+
},
|
|
488
|
+
one: {
|
|
489
|
+
cols: 1,
|
|
490
|
+
rows: 3
|
|
491
|
+
},
|
|
492
|
+
two: {
|
|
493
|
+
cols: 2,
|
|
494
|
+
rows: 3
|
|
495
|
+
},
|
|
496
|
+
three: {
|
|
497
|
+
cols: 3,
|
|
498
|
+
rows: 3
|
|
499
|
+
},
|
|
500
|
+
four: {
|
|
501
|
+
cols: 4,
|
|
502
|
+
rows: 3
|
|
503
|
+
},
|
|
504
|
+
"grid-4x5": {
|
|
505
|
+
cols: 4,
|
|
506
|
+
rows: 5
|
|
507
|
+
},
|
|
508
|
+
"grid-3x6": {
|
|
509
|
+
cols: 3,
|
|
510
|
+
rows: 6
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
function cubeIconCells(icon) {
|
|
514
|
+
const shape = SHAPES[icon];
|
|
515
|
+
if (!shape) return null;
|
|
516
|
+
const { cols, rows } = shape;
|
|
517
|
+
const gap = 1.6;
|
|
518
|
+
const size = Math.min((17 - gap * (cols - 1)) / cols, (17 - gap * (rows - 1)) / rows);
|
|
519
|
+
const w = cols * size + gap * (cols - 1);
|
|
520
|
+
const h = rows * size + gap * (rows - 1);
|
|
521
|
+
const out = [];
|
|
522
|
+
for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) out.push({
|
|
523
|
+
x: cols === 1 ? 3.5 : 12 - w / 2 + c * (size + gap),
|
|
524
|
+
y: 12 - h / 2 + r * (size + gap),
|
|
525
|
+
w: cols === 1 ? 17 : size,
|
|
526
|
+
h: size
|
|
527
|
+
});
|
|
528
|
+
return out;
|
|
529
|
+
}
|
|
530
|
+
var CubeIcon = class CubeIcon {
|
|
531
|
+
icon = input.required(...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
|
|
532
|
+
inUse = input(false, ...ngDevMode ? [{ debugName: "inUse" }] : /* istanbul ignore next */ []);
|
|
533
|
+
cells = computed(() => cubeIconCells(this.icon()), ...ngDevMode ? [{ debugName: "cells" }] : /* istanbul ignore next */ []);
|
|
534
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
535
|
+
minVersion: "12.0.0",
|
|
536
|
+
version: "22.2.4",
|
|
537
|
+
ngImport: i0,
|
|
538
|
+
type: CubeIcon,
|
|
539
|
+
deps: [],
|
|
540
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
541
|
+
});
|
|
542
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
543
|
+
minVersion: "17.0.0",
|
|
544
|
+
version: "22.2.4",
|
|
545
|
+
type: CubeIcon,
|
|
546
|
+
isStandalone: true,
|
|
547
|
+
selector: "cube-icon",
|
|
548
|
+
inputs: {
|
|
549
|
+
icon: {
|
|
550
|
+
classPropertyName: "icon",
|
|
551
|
+
publicName: "icon",
|
|
552
|
+
isSignal: true,
|
|
553
|
+
isRequired: true,
|
|
554
|
+
transformFunction: null
|
|
555
|
+
},
|
|
556
|
+
inUse: {
|
|
557
|
+
classPropertyName: "inUse",
|
|
558
|
+
publicName: "inUse",
|
|
559
|
+
isSignal: true,
|
|
560
|
+
isRequired: false,
|
|
561
|
+
transformFunction: null
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
host: { properties: { "class.in-use": "inUse()" } },
|
|
565
|
+
ngImport: i0,
|
|
566
|
+
template: `
|
|
567
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
568
|
+
@if (cells(); as cs) {
|
|
569
|
+
@for (c of cs; track $index) {
|
|
570
|
+
<rect
|
|
571
|
+
class="cell"
|
|
572
|
+
[attr.x]="c.x"
|
|
573
|
+
[attr.y]="c.y"
|
|
574
|
+
[attr.width]="c.w"
|
|
575
|
+
[attr.height]="c.h"
|
|
576
|
+
rx="0.8"
|
|
577
|
+
/>
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
@switch (icon()) {
|
|
581
|
+
@case ('view') {
|
|
582
|
+
<rect x="4" y="4" width="7" height="7" rx="1.5" />
|
|
583
|
+
<rect x="13" y="4" width="7" height="7" rx="1.5" />
|
|
584
|
+
<rect x="4" y="13" width="7" height="7" rx="1.5" />
|
|
585
|
+
<rect x="13" y="13" width="7" height="7" rx="1.5" />
|
|
586
|
+
}
|
|
587
|
+
@case ('sort') {
|
|
588
|
+
<path d="M8 19V5M4.5 8.5 8 5l3.5 3.5M16 5v14M12.5 15.5 16 19l3.5-3.5" />
|
|
589
|
+
}
|
|
590
|
+
@case ('kept') {
|
|
591
|
+
<path d="M5 7h14M5 12h14M5 17h9" />
|
|
592
|
+
}
|
|
593
|
+
@case ('face') {
|
|
594
|
+
<path d="M12 3.5 20 8v8l-8 4.5L4 16V8Z" />
|
|
595
|
+
<path d="M4 8l8 4.5L20 8M12 12.5v8" />
|
|
596
|
+
}
|
|
597
|
+
@case ('added') {
|
|
598
|
+
<circle cx="12" cy="12" r="8" />
|
|
599
|
+
<path d="M12 7.5V12l3 2" />
|
|
600
|
+
}
|
|
601
|
+
@case ('up') {
|
|
602
|
+
<path d="M12 19V5M6.5 10.5 12 5l5.5 5.5" />
|
|
603
|
+
}
|
|
604
|
+
@case ('plus') {
|
|
605
|
+
<path d="M12 5v14M5 12h14" />
|
|
606
|
+
}
|
|
607
|
+
@case ('down') {
|
|
608
|
+
<path d="M12 5v14M6.5 13.5 12 19l5.5-5.5" />
|
|
609
|
+
}
|
|
610
|
+
@case ('names') {
|
|
611
|
+
<path d="M3.5 12.5 11 5h8v8l-7.5 7.5a1.5 1.5 0 0 1-2.1 0L3.5 14.6a1.5 1.5 0 0 1 0-2.1Z" />
|
|
612
|
+
<circle cx="15.2" cy="8.8" r="1.4" />
|
|
613
|
+
}
|
|
614
|
+
@case ('name') {
|
|
615
|
+
<path d="M5 18 9.5 6h1L15 18M6.6 14h6.8" />
|
|
616
|
+
<path
|
|
617
|
+
d="M17 11.5c1.6-1.2 3.5-.5 3.5 1.4V18M20.5 14.6c-2.6-.3-4 .4-4 1.8 0 1.9 2.7 2 4 .3"
|
|
618
|
+
/>
|
|
619
|
+
}
|
|
620
|
+
@case ('change') {
|
|
621
|
+
<path d="M4 20h4L19 9a2.8 2.8 0 0 0-4-4L4 16v4Z" />
|
|
622
|
+
<path d="M13.5 6.5l4 4" />
|
|
623
|
+
}
|
|
624
|
+
@case ('move') {
|
|
625
|
+
<path
|
|
626
|
+
d="M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-1"
|
|
627
|
+
/>
|
|
628
|
+
<path d="M2.5 13H12M9 10l3 3-3 3" />
|
|
629
|
+
}
|
|
630
|
+
@case ('place') {
|
|
631
|
+
<path
|
|
632
|
+
d="M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8Z"
|
|
633
|
+
/>
|
|
634
|
+
}
|
|
635
|
+
@case ('whose') {
|
|
636
|
+
<circle cx="9" cy="8" r="3.2" />
|
|
637
|
+
<path d="M3 19c.6-3.4 3-5.2 6-5.2s5.4 1.8 6 5.2" />
|
|
638
|
+
<path d="M16 5.5a3 3 0 0 1 0 5.6M18.5 14.4c1.4.8 2.3 2.4 2.5 4.6" />
|
|
639
|
+
}
|
|
640
|
+
@case ('library') {
|
|
641
|
+
<path d="M4 5h4v15H4zM10 5h4v15h-4z" />
|
|
642
|
+
<path d="m16 6 3.6-1 3 14.4-3.6 1z" />
|
|
643
|
+
}
|
|
644
|
+
@case ('mine') {
|
|
645
|
+
<circle cx="12" cy="8" r="3.4" />
|
|
646
|
+
<path d="M5 20c.7-4 3.5-6 7-6s6.3 2 7 6" />
|
|
647
|
+
}
|
|
648
|
+
@case ('shown') {
|
|
649
|
+
<path d="M3 12s3.2-6 9-6 9 6 9 6-3.2 6-9 6-9-6-9-6Z" />
|
|
650
|
+
<circle cx="12" cy="12" r="2.6" />
|
|
651
|
+
}
|
|
652
|
+
@case ('hidden') {
|
|
653
|
+
<path d="M3 12s3.2-6 9-6c1.6 0 3 .45 4.2 1.1M21 12s-3.2 6-9 6c-1.6 0-3-.45-4.2-1.1" />
|
|
654
|
+
<path d="M4.5 19.5 19.5 4.5" />
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
</svg>
|
|
658
|
+
`,
|
|
659
|
+
isInline: true,
|
|
660
|
+
styles: [":host{display:inline-block;width:var(--cube-icon-size, 34px);height:var(--cube-icon-size, 34px);line-height:0}svg{width:100%;height:100%;fill:none;stroke:var(--cube-icon-stroke, #1f2a26);stroke-width:var(--cube-icon-stroke-width, 1.7);stroke-linecap:round;stroke-linejoin:round}.cell{fill:var(--cube-icon-stroke, #1f2a26);stroke:none;opacity:var(--cube-icon-cell-opacity, .8)}:host(.in-use) svg{stroke:var(--cube-icon-in-use, #3b5a4c)}:host(.in-use) .cell{fill:var(--cube-icon-in-use, #3b5a4c)}\n"],
|
|
661
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
662
|
+
});
|
|
663
|
+
};
|
|
664
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
665
|
+
minVersion: "12.0.0",
|
|
666
|
+
version: "22.2.4",
|
|
667
|
+
ngImport: i0,
|
|
668
|
+
type: CubeIcon,
|
|
669
|
+
decorators: [{
|
|
670
|
+
type: Component,
|
|
671
|
+
args: [{
|
|
672
|
+
selector: "cube-icon",
|
|
673
|
+
template: `
|
|
674
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
675
|
+
@if (cells(); as cs) {
|
|
676
|
+
@for (c of cs; track $index) {
|
|
677
|
+
<rect
|
|
678
|
+
class="cell"
|
|
679
|
+
[attr.x]="c.x"
|
|
680
|
+
[attr.y]="c.y"
|
|
681
|
+
[attr.width]="c.w"
|
|
682
|
+
[attr.height]="c.h"
|
|
683
|
+
rx="0.8"
|
|
684
|
+
/>
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
@switch (icon()) {
|
|
688
|
+
@case ('view') {
|
|
689
|
+
<rect x="4" y="4" width="7" height="7" rx="1.5" />
|
|
690
|
+
<rect x="13" y="4" width="7" height="7" rx="1.5" />
|
|
691
|
+
<rect x="4" y="13" width="7" height="7" rx="1.5" />
|
|
692
|
+
<rect x="13" y="13" width="7" height="7" rx="1.5" />
|
|
693
|
+
}
|
|
694
|
+
@case ('sort') {
|
|
695
|
+
<path d="M8 19V5M4.5 8.5 8 5l3.5 3.5M16 5v14M12.5 15.5 16 19l3.5-3.5" />
|
|
696
|
+
}
|
|
697
|
+
@case ('kept') {
|
|
698
|
+
<path d="M5 7h14M5 12h14M5 17h9" />
|
|
699
|
+
}
|
|
700
|
+
@case ('face') {
|
|
701
|
+
<path d="M12 3.5 20 8v8l-8 4.5L4 16V8Z" />
|
|
702
|
+
<path d="M4 8l8 4.5L20 8M12 12.5v8" />
|
|
703
|
+
}
|
|
704
|
+
@case ('added') {
|
|
705
|
+
<circle cx="12" cy="12" r="8" />
|
|
706
|
+
<path d="M12 7.5V12l3 2" />
|
|
707
|
+
}
|
|
708
|
+
@case ('up') {
|
|
709
|
+
<path d="M12 19V5M6.5 10.5 12 5l5.5 5.5" />
|
|
710
|
+
}
|
|
711
|
+
@case ('plus') {
|
|
712
|
+
<path d="M12 5v14M5 12h14" />
|
|
713
|
+
}
|
|
714
|
+
@case ('down') {
|
|
715
|
+
<path d="M12 5v14M6.5 13.5 12 19l5.5-5.5" />
|
|
716
|
+
}
|
|
717
|
+
@case ('names') {
|
|
718
|
+
<path d="M3.5 12.5 11 5h8v8l-7.5 7.5a1.5 1.5 0 0 1-2.1 0L3.5 14.6a1.5 1.5 0 0 1 0-2.1Z" />
|
|
719
|
+
<circle cx="15.2" cy="8.8" r="1.4" />
|
|
720
|
+
}
|
|
721
|
+
@case ('name') {
|
|
722
|
+
<path d="M5 18 9.5 6h1L15 18M6.6 14h6.8" />
|
|
723
|
+
<path
|
|
724
|
+
d="M17 11.5c1.6-1.2 3.5-.5 3.5 1.4V18M20.5 14.6c-2.6-.3-4 .4-4 1.8 0 1.9 2.7 2 4 .3"
|
|
725
|
+
/>
|
|
726
|
+
}
|
|
727
|
+
@case ('change') {
|
|
728
|
+
<path d="M4 20h4L19 9a2.8 2.8 0 0 0-4-4L4 16v4Z" />
|
|
729
|
+
<path d="M13.5 6.5l4 4" />
|
|
730
|
+
}
|
|
731
|
+
@case ('move') {
|
|
732
|
+
<path
|
|
733
|
+
d="M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-1"
|
|
734
|
+
/>
|
|
735
|
+
<path d="M2.5 13H12M9 10l3 3-3 3" />
|
|
736
|
+
}
|
|
737
|
+
@case ('place') {
|
|
738
|
+
<path
|
|
739
|
+
d="M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8Z"
|
|
740
|
+
/>
|
|
741
|
+
}
|
|
742
|
+
@case ('whose') {
|
|
743
|
+
<circle cx="9" cy="8" r="3.2" />
|
|
744
|
+
<path d="M3 19c.6-3.4 3-5.2 6-5.2s5.4 1.8 6 5.2" />
|
|
745
|
+
<path d="M16 5.5a3 3 0 0 1 0 5.6M18.5 14.4c1.4.8 2.3 2.4 2.5 4.6" />
|
|
746
|
+
}
|
|
747
|
+
@case ('library') {
|
|
748
|
+
<path d="M4 5h4v15H4zM10 5h4v15h-4z" />
|
|
749
|
+
<path d="m16 6 3.6-1 3 14.4-3.6 1z" />
|
|
750
|
+
}
|
|
751
|
+
@case ('mine') {
|
|
752
|
+
<circle cx="12" cy="8" r="3.4" />
|
|
753
|
+
<path d="M5 20c.7-4 3.5-6 7-6s6.3 2 7 6" />
|
|
754
|
+
}
|
|
755
|
+
@case ('shown') {
|
|
756
|
+
<path d="M3 12s3.2-6 9-6 9 6 9 6-3.2 6-9 6-9-6-9-6Z" />
|
|
757
|
+
<circle cx="12" cy="12" r="2.6" />
|
|
758
|
+
}
|
|
759
|
+
@case ('hidden') {
|
|
760
|
+
<path d="M3 12s3.2-6 9-6c1.6 0 3 .45 4.2 1.1M21 12s-3.2 6-9 6c-1.6 0-3-.45-4.2-1.1" />
|
|
761
|
+
<path d="M4.5 19.5 19.5 4.5" />
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
</svg>
|
|
765
|
+
`,
|
|
766
|
+
host: { "[class.in-use]": "inUse()" },
|
|
767
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
768
|
+
styles: [":host{display:inline-block;width:var(--cube-icon-size, 34px);height:var(--cube-icon-size, 34px);line-height:0}svg{width:100%;height:100%;fill:none;stroke:var(--cube-icon-stroke, #1f2a26);stroke-width:var(--cube-icon-stroke-width, 1.7);stroke-linecap:round;stroke-linejoin:round}.cell{fill:var(--cube-icon-stroke, #1f2a26);stroke:none;opacity:var(--cube-icon-cell-opacity, .8)}:host(.in-use) svg{stroke:var(--cube-icon-in-use, #3b5a4c)}:host(.in-use) .cell{fill:var(--cube-icon-in-use, #3b5a4c)}\n"]
|
|
769
|
+
}]
|
|
770
|
+
}],
|
|
771
|
+
propDecorators: {
|
|
772
|
+
icon: [{
|
|
773
|
+
type: i0.Input,
|
|
774
|
+
args: [{
|
|
775
|
+
isSignal: true,
|
|
776
|
+
alias: "icon",
|
|
777
|
+
required: true
|
|
778
|
+
}]
|
|
779
|
+
}],
|
|
780
|
+
inUse: [{
|
|
781
|
+
type: i0.Input,
|
|
782
|
+
args: [{
|
|
783
|
+
isSignal: true,
|
|
784
|
+
alias: "inUse",
|
|
785
|
+
required: false
|
|
786
|
+
}]
|
|
787
|
+
}]
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
const CONTEXT_PART_ORDER = [
|
|
791
|
+
"names",
|
|
792
|
+
"change",
|
|
793
|
+
"view",
|
|
794
|
+
"sort",
|
|
795
|
+
"move",
|
|
796
|
+
"whose",
|
|
797
|
+
"hide"
|
|
798
|
+
];
|
|
799
|
+
function orderParts(parts) {
|
|
800
|
+
const unique = [...new Set(parts)];
|
|
801
|
+
return [...CONTEXT_PART_ORDER.filter((p) => unique.includes(p)), ...unique.filter((p) => !CONTEXT_PART_ORDER.includes(p))];
|
|
802
|
+
}
|
|
803
|
+
const CONTEXT_CUBE_SOURCE = new InjectionToken("CONTEXT_CUBE_SOURCE");
|
|
804
|
+
const CONTEXT_CUBE_WORDS = new InjectionToken("CONTEXT_CUBE_WORDS");
|
|
805
|
+
const PART_ICONS = { hide: "shown" };
|
|
806
|
+
function partsLevel(parts, words, now = {}) {
|
|
807
|
+
return orderParts(parts).map((p) => ({
|
|
808
|
+
key: p,
|
|
809
|
+
title: words.parts[p]?.title ?? "",
|
|
810
|
+
line: now[p]?.line !== void 0 ? now[p]?.line : words.parts[p]?.line ?? null,
|
|
811
|
+
icon: now[p]?.icon ?? PART_ICONS[p] ?? p,
|
|
812
|
+
data: p
|
|
813
|
+
}));
|
|
814
|
+
}
|
|
815
|
+
const VIEW_KEYS = [
|
|
816
|
+
"square",
|
|
817
|
+
"one",
|
|
818
|
+
"two",
|
|
819
|
+
"three",
|
|
820
|
+
"four",
|
|
821
|
+
"grid-4x5",
|
|
822
|
+
"grid-3x6"
|
|
823
|
+
];
|
|
824
|
+
const isView = (v) => VIEW_KEYS.includes(v);
|
|
825
|
+
function gridFor(view, count) {
|
|
826
|
+
const n = Math.max(1, count);
|
|
827
|
+
switch (view) {
|
|
828
|
+
case "square": {
|
|
829
|
+
const side = Math.max(1, Math.ceil(Math.sqrt(n)));
|
|
830
|
+
return {
|
|
831
|
+
cols: side,
|
|
832
|
+
rows: side
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
case "one":
|
|
836
|
+
case "two":
|
|
837
|
+
case "three":
|
|
838
|
+
case "four": {
|
|
839
|
+
const cols = {
|
|
840
|
+
one: 1,
|
|
841
|
+
two: 2,
|
|
842
|
+
three: 3,
|
|
843
|
+
four: 4
|
|
844
|
+
}[view];
|
|
845
|
+
return {
|
|
846
|
+
cols,
|
|
847
|
+
rows: Math.ceil(n / cols)
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
case "grid-4x5":
|
|
851
|
+
case "grid-3x6": {
|
|
852
|
+
const [cols, rows] = view === "grid-4x5" ? [4, 5] : [3, 6];
|
|
853
|
+
return {
|
|
854
|
+
cols,
|
|
855
|
+
rows: rows * Math.ceil(n / (cols * rows))
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
function sortItems(items, by, dir) {
|
|
861
|
+
const sign = dir === "down" ? -1 : 1;
|
|
862
|
+
const known = (v) => v !== null && v !== void 0 && v !== "";
|
|
863
|
+
return items.map((item, at) => ({
|
|
864
|
+
item,
|
|
865
|
+
at,
|
|
866
|
+
value: by(item)
|
|
867
|
+
})).sort((a, b) => {
|
|
868
|
+
const ka = known(a.value);
|
|
869
|
+
const kb = known(b.value);
|
|
870
|
+
if (!ka || !kb) return Number(!ka) - Number(!kb) || a.at - b.at;
|
|
871
|
+
return sign * compare(a.value, b.value) || a.at - b.at;
|
|
872
|
+
}).map((x) => x.item);
|
|
873
|
+
}
|
|
874
|
+
function compare(a, b) {
|
|
875
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
876
|
+
return String(a).localeCompare(String(b));
|
|
877
|
+
}
|
|
878
|
+
function namesLevel(names, words, opts = {}) {
|
|
879
|
+
const tiles = [...names.filter((n) => n.current), ...names.filter((n) => !n.current).reverse()].map((n, i) => ({
|
|
880
|
+
key: `name:${i}:${n.name}`,
|
|
881
|
+
title: n.name,
|
|
882
|
+
line: words.names.line?.(n) ?? null,
|
|
883
|
+
icon: "name",
|
|
884
|
+
inUse: n.current,
|
|
885
|
+
data: { name: n }
|
|
886
|
+
}));
|
|
887
|
+
if (opts.canAdd) tiles.push({
|
|
888
|
+
key: "name:+",
|
|
889
|
+
title: words.names.another.title,
|
|
890
|
+
line: words.names.another.line ?? null,
|
|
891
|
+
icon: "plus",
|
|
892
|
+
adds: true,
|
|
893
|
+
data: { another: true }
|
|
894
|
+
});
|
|
895
|
+
return tiles;
|
|
896
|
+
}
|
|
897
|
+
function hideLevel(hidden, words) {
|
|
898
|
+
return [{
|
|
899
|
+
key: "hide:shown",
|
|
900
|
+
title: words.hide.shown.title,
|
|
901
|
+
line: words.hide.shown.line ?? null,
|
|
902
|
+
icon: "shown",
|
|
903
|
+
inUse: !hidden,
|
|
904
|
+
data: false
|
|
905
|
+
}, {
|
|
906
|
+
key: "hide:hidden",
|
|
907
|
+
title: words.hide.hidden.title,
|
|
908
|
+
line: words.hide.hidden.line ?? null,
|
|
909
|
+
icon: "hidden",
|
|
910
|
+
inUse: hidden,
|
|
911
|
+
data: true
|
|
912
|
+
}];
|
|
913
|
+
}
|
|
914
|
+
function viewLevel(now, words, views = VIEW_KEYS) {
|
|
915
|
+
return views.map((v) => ({
|
|
916
|
+
key: "view:" + v,
|
|
917
|
+
title: words.views[v]?.title ?? "",
|
|
918
|
+
line: v === now ? null : words.views[v]?.line ?? null,
|
|
919
|
+
icon: v,
|
|
920
|
+
inUse: v === now,
|
|
921
|
+
data: v
|
|
922
|
+
}));
|
|
923
|
+
}
|
|
924
|
+
function directionWords(option, words) {
|
|
925
|
+
return {
|
|
926
|
+
up: option.up ?? words.directions.up,
|
|
927
|
+
down: option.down ?? words.directions.down
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
function sortLevel(options, now, words) {
|
|
931
|
+
return options.map((o) => {
|
|
932
|
+
const inUse = now.by === o.by;
|
|
933
|
+
const directed = o.directed !== false;
|
|
934
|
+
return {
|
|
935
|
+
key: "sort:" + o.by,
|
|
936
|
+
title: o.title,
|
|
937
|
+
line: inUse && directed ? directionWords(o, words)[now.dir].title : o.line ?? null,
|
|
938
|
+
icon: o.icon,
|
|
939
|
+
inUse,
|
|
940
|
+
data: o
|
|
941
|
+
};
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
function sortDirectionsLevel(option, now, words) {
|
|
945
|
+
const w = directionWords(option, words);
|
|
946
|
+
return ["up", "down"].map((dir) => ({
|
|
947
|
+
key: "dir:" + dir,
|
|
948
|
+
title: w[dir].title,
|
|
949
|
+
line: w[dir].line ?? null,
|
|
950
|
+
icon: dir,
|
|
951
|
+
inUse: now.by === option.by && now.dir === dir,
|
|
952
|
+
data: dir
|
|
953
|
+
}));
|
|
954
|
+
}
|
|
955
|
+
const TURNING_SIDES = 4;
|
|
956
|
+
function turningRows(pieces, own, cols = 3, rows = cols) {
|
|
957
|
+
const across = Math.max(1, Math.floor(cols));
|
|
958
|
+
const down = Math.max(1, Math.floor(rows));
|
|
959
|
+
const count = pieces.length + (own !== null ? 1 : 0);
|
|
960
|
+
const perRow = across * 4;
|
|
961
|
+
const rowCount = Math.max(down, Math.ceil(count / perRow));
|
|
962
|
+
const grid = Array.from({ length: rowCount }, () => Array.from({ length: 4 }, () => Array.from({ length: across }).fill(null)));
|
|
963
|
+
const front = [];
|
|
964
|
+
for (let r = 0; r < rowCount; r++) for (let c = 0; c < across; c++) front.push([r, c]);
|
|
965
|
+
const frontForPieces = own !== null ? front.slice(0, -1) : front;
|
|
966
|
+
if (own !== null) grid[rowCount - 1][0][across - 1] = own;
|
|
967
|
+
let next = 0;
|
|
968
|
+
for (const [r, c] of frontForPieces) {
|
|
969
|
+
if (next >= pieces.length) break;
|
|
970
|
+
grid[r][0][c] = pieces[next++];
|
|
971
|
+
}
|
|
972
|
+
for (let r = 0; r < rowCount && next < pieces.length; r++) for (let s = 1; s < 4 && next < pieces.length; s++) for (let c = 0; c < across && next < pieces.length; c++) grid[r][s][c] = pieces[next++];
|
|
973
|
+
return {
|
|
974
|
+
rows: grid,
|
|
975
|
+
sides: grid.map((row) => 1 + row.slice(1).filter((side) => side.some((t) => t !== null)).length)
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
function squareLevelFor(cell) {
|
|
979
|
+
return cell >= 280 ? 0 : cell >= 150 ? 1 : cell >= 100 ? 2 : cell >= 70 ? 3 : 4;
|
|
980
|
+
}
|
|
981
|
+
function squareGap(n) {
|
|
982
|
+
return n <= 2 ? 12 : n === 3 ? 10 : n === 4 ? 8 : 5;
|
|
983
|
+
}
|
|
984
|
+
const SQUARE_MAX_SIDE = 880;
|
|
985
|
+
const SQUARE_LIST_ROW = 76;
|
|
986
|
+
function squareLayout(view, count, room, opts = {}) {
|
|
987
|
+
const n = Math.max(0, count);
|
|
988
|
+
const grid = gridFor(view, n);
|
|
989
|
+
const cols = grid.cols;
|
|
990
|
+
const rows = view === "square" ? grid.rows : Math.max(1, Math.ceil(n / cols));
|
|
991
|
+
const width = Math.max(0, Math.min(view === "square" ? Math.min(room.width, room.tall) : room.width, opts.maxSide ?? 880));
|
|
992
|
+
const list = view === "one";
|
|
993
|
+
const gap = list ? 8 : squareGap(Math.max(cols, Math.min(rows, 5)));
|
|
994
|
+
const cell = Math.max(0, (width - gap * (cols - 1)) / cols);
|
|
995
|
+
const rowHeight = list ? opts.listRow ?? 76 : cell;
|
|
996
|
+
return {
|
|
997
|
+
cols,
|
|
998
|
+
rows,
|
|
999
|
+
width,
|
|
1000
|
+
height: rows * rowHeight + gap * (rows - 1),
|
|
1001
|
+
gap,
|
|
1002
|
+
cell,
|
|
1003
|
+
rowHeight,
|
|
1004
|
+
level: list ? 1 : squareLevelFor(cell),
|
|
1005
|
+
list,
|
|
1006
|
+
open: cols * rows - n
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
var CubeSquareTile = class CubeSquareTile {
|
|
1010
|
+
template = inject(TemplateRef);
|
|
1011
|
+
cubeSquareTile = input(...ngDevMode ? [void 0, { debugName: "cubeSquareTile" }] : /* istanbul ignore next */ []);
|
|
1012
|
+
static ngTemplateContextGuard(_dir, ctx) {
|
|
1013
|
+
return true;
|
|
1014
|
+
}
|
|
1015
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1016
|
+
minVersion: "12.0.0",
|
|
1017
|
+
version: "22.2.4",
|
|
1018
|
+
ngImport: i0,
|
|
1019
|
+
type: CubeSquareTile,
|
|
1020
|
+
deps: [],
|
|
1021
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
1022
|
+
});
|
|
1023
|
+
static ɵdir = i0.ɵɵngDeclareDirective({
|
|
1024
|
+
minVersion: "17.1.0",
|
|
1025
|
+
version: "22.2.4",
|
|
1026
|
+
type: CubeSquareTile,
|
|
1027
|
+
isStandalone: true,
|
|
1028
|
+
selector: "ng-template[cubeSquareTile]",
|
|
1029
|
+
inputs: { cubeSquareTile: {
|
|
1030
|
+
classPropertyName: "cubeSquareTile",
|
|
1031
|
+
publicName: "cubeSquareTile",
|
|
1032
|
+
isSignal: true,
|
|
1033
|
+
isRequired: false,
|
|
1034
|
+
transformFunction: null
|
|
1035
|
+
} },
|
|
1036
|
+
ngImport: i0
|
|
1037
|
+
});
|
|
1038
|
+
};
|
|
1039
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1040
|
+
minVersion: "12.0.0",
|
|
1041
|
+
version: "22.2.4",
|
|
1042
|
+
ngImport: i0,
|
|
1043
|
+
type: CubeSquareTile,
|
|
1044
|
+
decorators: [{
|
|
1045
|
+
type: Directive,
|
|
1046
|
+
args: [{ selector: "ng-template[cubeSquareTile]" }]
|
|
1047
|
+
}],
|
|
1048
|
+
propDecorators: { cubeSquareTile: [{
|
|
1049
|
+
type: i0.Input,
|
|
1050
|
+
args: [{
|
|
1051
|
+
isSignal: true,
|
|
1052
|
+
alias: "cubeSquareTile",
|
|
1053
|
+
required: false
|
|
1054
|
+
}]
|
|
1055
|
+
}] }
|
|
1056
|
+
});
|
|
1057
|
+
function turningFront(view, across = 3) {
|
|
1058
|
+
if (view === "square") return {
|
|
1059
|
+
cols: across,
|
|
1060
|
+
rows: across
|
|
1061
|
+
};
|
|
1062
|
+
if (view === "grid-4x5") return {
|
|
1063
|
+
cols: 4,
|
|
1064
|
+
rows: 5
|
|
1065
|
+
};
|
|
1066
|
+
if (view === "grid-3x6") return {
|
|
1067
|
+
cols: 3,
|
|
1068
|
+
rows: 6
|
|
1069
|
+
};
|
|
1070
|
+
return null;
|
|
1071
|
+
}
|
|
1072
|
+
const TURNING_BELOW = 640;
|
|
1073
|
+
const TURNING_NUDGE_UNTIL = 3;
|
|
1074
|
+
let turnedHere = 0;
|
|
1075
|
+
const readTurned = (key) => {
|
|
1076
|
+
if (!key) return turnedHere;
|
|
1077
|
+
try {
|
|
1078
|
+
return Number(localStorage.getItem(key)) || 0;
|
|
1079
|
+
} catch {
|
|
1080
|
+
return turnedHere;
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
const noteTurned = (key) => {
|
|
1084
|
+
turnedHere++;
|
|
1085
|
+
if (!key) return;
|
|
1086
|
+
try {
|
|
1087
|
+
localStorage.setItem(key, String(readTurned(key) + 1));
|
|
1088
|
+
} catch {}
|
|
1089
|
+
};
|
|
1090
|
+
const reducedMotion = () => typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1091
|
+
var CubeSquare = class CubeSquare {
|
|
1092
|
+
tiles = input.required(...ngDevMode ? [{ debugName: "tiles" }] : /* istanbul ignore next */ []);
|
|
1093
|
+
view = input("square", ...ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []);
|
|
1094
|
+
maxSide = input(880, ...ngDevMode ? [{ debugName: "maxSide" }] : /* istanbul ignore next */ []);
|
|
1095
|
+
listRow = input(76, ...ngDevMode ? [{ debugName: "listRow" }] : /* istanbul ignore next */ []);
|
|
1096
|
+
dashed = input(false, ...ngDevMode ? [{ debugName: "dashed" }] : /* istanbul ignore next */ []);
|
|
1097
|
+
keyOf = input((_, i) => i, ...ngDevMode ? [{ debugName: "keyOf" }] : /* istanbul ignore next */ []);
|
|
1098
|
+
turning = input(false, ...ngDevMode ? [{ debugName: "turning" }] : /* istanbul ignore next */ []);
|
|
1099
|
+
turnBelow = input(640, ...ngDevMode ? [{ debugName: "turnBelow" }] : /* istanbul ignore next */ []);
|
|
1100
|
+
across = input(3, ...ngDevMode ? [{ debugName: "across" }] : /* istanbul ignore next */ []);
|
|
1101
|
+
isOwn = input(null, ...ngDevMode ? [{ debugName: "isOwn" }] : /* istanbul ignore next */ []);
|
|
1102
|
+
nudgeKey = input(null, ...ngDevMode ? [{ debugName: "nudgeKey" }] : /* istanbul ignore next */ []);
|
|
1103
|
+
tile = contentChild(CubeSquareTile, ...ngDevMode ? [{ debugName: "tile" }] : /* istanbul ignore next */ []);
|
|
1104
|
+
grid = viewChild("grid", ...ngDevMode ? [{ debugName: "grid" }] : /* istanbul ignore next */ []);
|
|
1105
|
+
room = signal({
|
|
1106
|
+
width: 0,
|
|
1107
|
+
tall: 0
|
|
1108
|
+
}, ...ngDevMode ? [{ debugName: "room" }] : /* istanbul ignore next */ []);
|
|
1109
|
+
front = computed(() => {
|
|
1110
|
+
if (!this.turning()) return null;
|
|
1111
|
+
if ((this.room().width || 354) >= this.turnBelow()) return null;
|
|
1112
|
+
const front = turningFront(this.view(), Math.max(1, Math.floor(this.across())));
|
|
1113
|
+
return front && this.tiles().length > front.cols * front.rows ? front : null;
|
|
1114
|
+
}, ...ngDevMode ? [{ debugName: "front" }] : /* istanbul ignore next */ []);
|
|
1115
|
+
layout = computed(() => {
|
|
1116
|
+
const r = this.room();
|
|
1117
|
+
const width = r.width || 354;
|
|
1118
|
+
const room = {
|
|
1119
|
+
width,
|
|
1120
|
+
tall: r.tall || width
|
|
1121
|
+
};
|
|
1122
|
+
const opts = {
|
|
1123
|
+
maxSide: this.maxSide(),
|
|
1124
|
+
listRow: this.listRow()
|
|
1125
|
+
};
|
|
1126
|
+
const front = this.front();
|
|
1127
|
+
if (!front) return squareLayout(this.view(), this.tiles().length, room, opts);
|
|
1128
|
+
const full = squareLayout(this.view(), front.cols * front.rows, room, opts);
|
|
1129
|
+
const rows = this.rings()?.rows.length ?? front.rows;
|
|
1130
|
+
return {
|
|
1131
|
+
...full,
|
|
1132
|
+
rows,
|
|
1133
|
+
height: rows * full.rowHeight + full.gap * (rows - 1),
|
|
1134
|
+
open: 0
|
|
1135
|
+
};
|
|
1136
|
+
}, ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
|
|
1137
|
+
rings = computed(() => {
|
|
1138
|
+
const front = this.front();
|
|
1139
|
+
if (!front) return null;
|
|
1140
|
+
const isOwn = this.isOwn();
|
|
1141
|
+
const tiles = this.tiles();
|
|
1142
|
+
const own = isOwn ? tiles.find((t) => isOwn(t)) ?? null : null;
|
|
1143
|
+
return turningRows(own === null ? tiles : tiles.filter((t) => t !== own), own, front.cols, front.rows);
|
|
1144
|
+
}, ...ngDevMode ? [{ debugName: "rings" }] : /* istanbul ignore next */ []);
|
|
1145
|
+
indexes = computed(() => new Map(this.tiles().map((t, i) => [t, i])), ...ngDevMode ? [{ debugName: "indexes" }] : /* istanbul ignore next */ []);
|
|
1146
|
+
indexOf(t) {
|
|
1147
|
+
return this.indexes().get(t) ?? 0;
|
|
1148
|
+
}
|
|
1149
|
+
openPlaces = computed(() => Array.from({ length: this.layout().open }, (_, i) => i), ...ngDevMode ? [{ debugName: "openPlaces" }] : /* istanbul ignore next */ []);
|
|
1150
|
+
angles = signal({}, ...ngDevMode ? [{ debugName: "angles" }] : /* istanbul ignore next */ []);
|
|
1151
|
+
dragging = signal(null, ...ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []);
|
|
1152
|
+
still = signal(reducedMotion(), ...ngDevMode ? [{ debugName: "still" }] : /* istanbul ignore next */ []);
|
|
1153
|
+
nudging = signal(false, ...ngDevMode ? [{ debugName: "nudging" }] : /* istanbul ignore next */ []);
|
|
1154
|
+
drag = null;
|
|
1155
|
+
fingers = /* @__PURE__ */ new Set();
|
|
1156
|
+
suppressClick = false;
|
|
1157
|
+
nudged = false;
|
|
1158
|
+
timers = [];
|
|
1159
|
+
host = inject(ElementRef).nativeElement;
|
|
1160
|
+
angle(row) {
|
|
1161
|
+
return this.angles()[row] ?? 0;
|
|
1162
|
+
}
|
|
1163
|
+
sideOf(row) {
|
|
1164
|
+
const sides = 4;
|
|
1165
|
+
return (Math.round(-this.angle(row) / 90) % sides + sides) % sides;
|
|
1166
|
+
}
|
|
1167
|
+
filled(row) {
|
|
1168
|
+
return this.rings()?.sides[row] ?? 1;
|
|
1169
|
+
}
|
|
1170
|
+
down(row, e) {
|
|
1171
|
+
this.fingers.add(e.pointerId);
|
|
1172
|
+
if (this.fingers.size > 1) {
|
|
1173
|
+
this.cancelDrag();
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
if (this.filled(row) <= 1) return;
|
|
1177
|
+
this.drag = {
|
|
1178
|
+
row,
|
|
1179
|
+
id: e.pointerId,
|
|
1180
|
+
x: e.clientX,
|
|
1181
|
+
y: e.clientY,
|
|
1182
|
+
base: this.angle(row),
|
|
1183
|
+
moved: false
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
move(row, e) {
|
|
1187
|
+
const drag = this.drag;
|
|
1188
|
+
if (!drag || drag.row !== row || drag.id !== e.pointerId) return;
|
|
1189
|
+
const dx = e.clientX - drag.x;
|
|
1190
|
+
const dy = e.clientY - drag.y;
|
|
1191
|
+
if (!drag.moved) {
|
|
1192
|
+
if (Math.abs(dx) < 8 || Math.abs(dx) < Math.abs(dy)) return;
|
|
1193
|
+
drag.moved = true;
|
|
1194
|
+
this.dragging.set(row);
|
|
1195
|
+
e.currentTarget?.setPointerCapture?.(e.pointerId);
|
|
1196
|
+
}
|
|
1197
|
+
const width = this.layout().width || 354;
|
|
1198
|
+
this.angles.update((a) => ({
|
|
1199
|
+
...a,
|
|
1200
|
+
[row]: drag.base + dx / width * 90
|
|
1201
|
+
}));
|
|
1202
|
+
}
|
|
1203
|
+
up(row, e) {
|
|
1204
|
+
this.fingers.delete(e.pointerId);
|
|
1205
|
+
const drag = this.drag;
|
|
1206
|
+
if (!drag || drag.row !== row || drag.id !== e.pointerId) return;
|
|
1207
|
+
this.drag = null;
|
|
1208
|
+
if (!drag.moved) return;
|
|
1209
|
+
this.dragging.set(null);
|
|
1210
|
+
this.suppressClick = true;
|
|
1211
|
+
setTimeout(() => this.suppressClick = false);
|
|
1212
|
+
const moved = this.angle(row) - drag.base;
|
|
1213
|
+
const steps = Math.abs(moved) > 12 ? Math.sign(moved) * Math.max(1, Math.round(Math.abs(moved) / 90)) : 0;
|
|
1214
|
+
this.settle(row, drag.base, steps);
|
|
1215
|
+
}
|
|
1216
|
+
cancelDrag() {
|
|
1217
|
+
const drag = this.drag;
|
|
1218
|
+
this.drag = null;
|
|
1219
|
+
if (!drag?.moved) return;
|
|
1220
|
+
this.dragging.set(null);
|
|
1221
|
+
this.angles.update((a) => ({
|
|
1222
|
+
...a,
|
|
1223
|
+
[drag.row]: drag.base
|
|
1224
|
+
}));
|
|
1225
|
+
}
|
|
1226
|
+
settle(row, base, steps) {
|
|
1227
|
+
const filled = this.filled(row);
|
|
1228
|
+
const sideAt = (s) => (Math.round(-(base + s * 90) / 90) % 4 + 4) % 4;
|
|
1229
|
+
let n = steps;
|
|
1230
|
+
while (n !== 0 && sideAt(n) >= filled) n += Math.sign(n);
|
|
1231
|
+
this.angles.update((a) => ({
|
|
1232
|
+
...a,
|
|
1233
|
+
[row]: base + n * 90
|
|
1234
|
+
}));
|
|
1235
|
+
if (n !== 0) noteTurned(this.nudgeKey());
|
|
1236
|
+
}
|
|
1237
|
+
key(row, e) {
|
|
1238
|
+
if (e.key !== "ArrowRight" && e.key !== "ArrowLeft") return;
|
|
1239
|
+
if (this.filled(row) <= 1) return;
|
|
1240
|
+
e.preventDefault();
|
|
1241
|
+
const col = this.focusedColumn(e.target);
|
|
1242
|
+
this.settle(row, this.angle(row), e.key === "ArrowRight" ? -1 : 1);
|
|
1243
|
+
setTimeout(() => this.focusSide(row, col));
|
|
1244
|
+
}
|
|
1245
|
+
focusedColumn(target) {
|
|
1246
|
+
const cell = target?.closest(".cs-cell, .cs-place");
|
|
1247
|
+
const side = cell?.parentElement;
|
|
1248
|
+
return cell && side ? Array.from(side.children).indexOf(cell) : 0;
|
|
1249
|
+
}
|
|
1250
|
+
focusSide(row, col) {
|
|
1251
|
+
const side = this.host.querySelector(`.cs-row[data-row="${row}"] .cs-side[data-side="${this.sideOf(row)}"]`);
|
|
1252
|
+
if (!side) return;
|
|
1253
|
+
const cells = Array.from(side.children);
|
|
1254
|
+
const order = [cells[col], ...cells].filter(Boolean);
|
|
1255
|
+
const focusable = "button, a[href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])";
|
|
1256
|
+
for (const cell of order) {
|
|
1257
|
+
const el = cell.matches(focusable) ? cell : cell.querySelector(focusable);
|
|
1258
|
+
if (el) {
|
|
1259
|
+
el.focus();
|
|
1260
|
+
return;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
side.closest(".cs-row")?.focus();
|
|
1264
|
+
}
|
|
1265
|
+
nudge() {
|
|
1266
|
+
const rings = this.rings();
|
|
1267
|
+
if (this.nudged || !rings || reducedMotion()) return;
|
|
1268
|
+
if (readTurned(this.nudgeKey()) >= 3) return;
|
|
1269
|
+
const rows = rings.sides.flatMap((s, i) => s > 1 ? [i] : []);
|
|
1270
|
+
if (!rows.length) return;
|
|
1271
|
+
this.nudged = true;
|
|
1272
|
+
this.nudging.set(true);
|
|
1273
|
+
const set = (row, angle) => {
|
|
1274
|
+
if (this.drag || this.dragging() !== null) return;
|
|
1275
|
+
this.angles.update((a) => ({
|
|
1276
|
+
...a,
|
|
1277
|
+
[row]: angle
|
|
1278
|
+
}));
|
|
1279
|
+
};
|
|
1280
|
+
rows.forEach((row, i) => {
|
|
1281
|
+
this.timers.push(setTimeout(() => set(row, -22), 500 + i * 180), setTimeout(() => set(row, 0), 1020 + i * 180));
|
|
1282
|
+
});
|
|
1283
|
+
this.timers.push(setTimeout(() => this.nudging.set(false), 1600 + rows.length * 180));
|
|
1284
|
+
}
|
|
1285
|
+
constructor() {
|
|
1286
|
+
const host = this.host;
|
|
1287
|
+
const destroy = inject(DestroyRef);
|
|
1288
|
+
const swallow = (e) => {
|
|
1289
|
+
if (!this.suppressClick) return;
|
|
1290
|
+
e.stopPropagation();
|
|
1291
|
+
e.preventDefault();
|
|
1292
|
+
};
|
|
1293
|
+
host.addEventListener("click", swallow, true);
|
|
1294
|
+
destroy.onDestroy(() => {
|
|
1295
|
+
host.removeEventListener("click", swallow, true);
|
|
1296
|
+
this.timers.forEach(clearTimeout);
|
|
1297
|
+
});
|
|
1298
|
+
effect(() => {
|
|
1299
|
+
if (this.rings()) untracked(() => this.timers.push(setTimeout(() => this.nudge())));
|
|
1300
|
+
});
|
|
1301
|
+
afterNextRender(() => {
|
|
1302
|
+
const measure = () => this.room.set({
|
|
1303
|
+
width: host.clientWidth,
|
|
1304
|
+
tall: Math.max(320, window.innerHeight - 48)
|
|
1305
|
+
});
|
|
1306
|
+
measure();
|
|
1307
|
+
const watch = typeof ResizeObserver === "function" ? new ResizeObserver(measure) : null;
|
|
1308
|
+
watch?.observe(host);
|
|
1309
|
+
window.addEventListener("resize", measure);
|
|
1310
|
+
destroy.onDestroy(() => {
|
|
1311
|
+
watch?.disconnect();
|
|
1312
|
+
window.removeEventListener("resize", measure);
|
|
1313
|
+
});
|
|
1314
|
+
});
|
|
1315
|
+
let before = 0;
|
|
1316
|
+
let beforeView = null;
|
|
1317
|
+
effect(() => {
|
|
1318
|
+
const { cols, list } = this.layout();
|
|
1319
|
+
const view = this.view();
|
|
1320
|
+
const el = this.grid()?.nativeElement;
|
|
1321
|
+
if (el && before && cols !== before && view === beforeView && !list && !reducedMotion() && typeof el.animate === "function") el.animate([{ transform: `scale(${cols / before})` }, { transform: "none" }], {
|
|
1322
|
+
duration: 420,
|
|
1323
|
+
easing: "cubic-bezier(.2,.7,.2,1)"
|
|
1324
|
+
});
|
|
1325
|
+
before = cols;
|
|
1326
|
+
beforeView = view;
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1330
|
+
minVersion: "12.0.0",
|
|
1331
|
+
version: "22.2.4",
|
|
1332
|
+
ngImport: i0,
|
|
1333
|
+
type: CubeSquare,
|
|
1334
|
+
deps: [],
|
|
1335
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
1336
|
+
});
|
|
1337
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
1338
|
+
minVersion: "17.0.0",
|
|
1339
|
+
version: "22.2.4",
|
|
1340
|
+
type: CubeSquare,
|
|
1341
|
+
isStandalone: true,
|
|
1342
|
+
selector: "cube-square",
|
|
1343
|
+
inputs: {
|
|
1344
|
+
tiles: {
|
|
1345
|
+
classPropertyName: "tiles",
|
|
1346
|
+
publicName: "tiles",
|
|
1347
|
+
isSignal: true,
|
|
1348
|
+
isRequired: true,
|
|
1349
|
+
transformFunction: null
|
|
1350
|
+
},
|
|
1351
|
+
view: {
|
|
1352
|
+
classPropertyName: "view",
|
|
1353
|
+
publicName: "view",
|
|
1354
|
+
isSignal: true,
|
|
1355
|
+
isRequired: false,
|
|
1356
|
+
transformFunction: null
|
|
1357
|
+
},
|
|
1358
|
+
maxSide: {
|
|
1359
|
+
classPropertyName: "maxSide",
|
|
1360
|
+
publicName: "maxSide",
|
|
1361
|
+
isSignal: true,
|
|
1362
|
+
isRequired: false,
|
|
1363
|
+
transformFunction: null
|
|
1364
|
+
},
|
|
1365
|
+
listRow: {
|
|
1366
|
+
classPropertyName: "listRow",
|
|
1367
|
+
publicName: "listRow",
|
|
1368
|
+
isSignal: true,
|
|
1369
|
+
isRequired: false,
|
|
1370
|
+
transformFunction: null
|
|
1371
|
+
},
|
|
1372
|
+
dashed: {
|
|
1373
|
+
classPropertyName: "dashed",
|
|
1374
|
+
publicName: "dashed",
|
|
1375
|
+
isSignal: true,
|
|
1376
|
+
isRequired: false,
|
|
1377
|
+
transformFunction: null
|
|
1378
|
+
},
|
|
1379
|
+
keyOf: {
|
|
1380
|
+
classPropertyName: "keyOf",
|
|
1381
|
+
publicName: "keyOf",
|
|
1382
|
+
isSignal: true,
|
|
1383
|
+
isRequired: false,
|
|
1384
|
+
transformFunction: null
|
|
1385
|
+
},
|
|
1386
|
+
turning: {
|
|
1387
|
+
classPropertyName: "turning",
|
|
1388
|
+
publicName: "turning",
|
|
1389
|
+
isSignal: true,
|
|
1390
|
+
isRequired: false,
|
|
1391
|
+
transformFunction: null
|
|
1392
|
+
},
|
|
1393
|
+
turnBelow: {
|
|
1394
|
+
classPropertyName: "turnBelow",
|
|
1395
|
+
publicName: "turnBelow",
|
|
1396
|
+
isSignal: true,
|
|
1397
|
+
isRequired: false,
|
|
1398
|
+
transformFunction: null
|
|
1399
|
+
},
|
|
1400
|
+
across: {
|
|
1401
|
+
classPropertyName: "across",
|
|
1402
|
+
publicName: "across",
|
|
1403
|
+
isSignal: true,
|
|
1404
|
+
isRequired: false,
|
|
1405
|
+
transformFunction: null
|
|
1406
|
+
},
|
|
1407
|
+
isOwn: {
|
|
1408
|
+
classPropertyName: "isOwn",
|
|
1409
|
+
publicName: "isOwn",
|
|
1410
|
+
isSignal: true,
|
|
1411
|
+
isRequired: false,
|
|
1412
|
+
transformFunction: null
|
|
1413
|
+
},
|
|
1414
|
+
nudgeKey: {
|
|
1415
|
+
classPropertyName: "nudgeKey",
|
|
1416
|
+
publicName: "nudgeKey",
|
|
1417
|
+
isSignal: true,
|
|
1418
|
+
isRequired: false,
|
|
1419
|
+
transformFunction: null
|
|
1420
|
+
}
|
|
1421
|
+
},
|
|
1422
|
+
queries: [{
|
|
1423
|
+
propertyName: "tile",
|
|
1424
|
+
first: true,
|
|
1425
|
+
predicate: CubeSquareTile,
|
|
1426
|
+
descendants: true,
|
|
1427
|
+
isSignal: true
|
|
1428
|
+
}],
|
|
1429
|
+
viewQueries: [{
|
|
1430
|
+
propertyName: "grid",
|
|
1431
|
+
first: true,
|
|
1432
|
+
predicate: ["grid"],
|
|
1433
|
+
descendants: true,
|
|
1434
|
+
isSignal: true
|
|
1435
|
+
}],
|
|
1436
|
+
ngImport: i0,
|
|
1437
|
+
template: `
|
|
1438
|
+
@let sq = layout();
|
|
1439
|
+
@if (rings(); as r) {
|
|
1440
|
+
<div
|
|
1441
|
+
class="cs-turning"
|
|
1442
|
+
[class]="'cs-turning cs-l' + sq.level"
|
|
1443
|
+
[class.cs-dashed]="dashed()"
|
|
1444
|
+
[attr.data-level]="sq.level"
|
|
1445
|
+
[style.width.px]="sq.width"
|
|
1446
|
+
[style.--cs-gap.px]="sq.gap"
|
|
1447
|
+
>
|
|
1448
|
+
@for (row of r.rows; track ri; let ri = $index) {
|
|
1449
|
+
<div
|
|
1450
|
+
class="cs-row"
|
|
1451
|
+
[class.cs-turns]="r.sides[ri] > 1"
|
|
1452
|
+
[attr.data-row]="ri"
|
|
1453
|
+
[style.height.px]="sq.rowHeight"
|
|
1454
|
+
(pointerdown)="down(ri, $event)"
|
|
1455
|
+
(pointermove)="move(ri, $event)"
|
|
1456
|
+
(pointerup)="up(ri, $event)"
|
|
1457
|
+
(pointercancel)="up(ri, $event)"
|
|
1458
|
+
(keydown)="key(ri, $event)"
|
|
1459
|
+
>
|
|
1460
|
+
@if (r.sides[ri] > 1) {
|
|
1461
|
+
<span class="cs-edge" aria-hidden="true"></span>
|
|
1462
|
+
}
|
|
1463
|
+
<div
|
|
1464
|
+
class="cs-band"
|
|
1465
|
+
[class.cs-still]="dragging() === ri || still()"
|
|
1466
|
+
[class.cs-nudging]="nudging()"
|
|
1467
|
+
[style.transform]="
|
|
1468
|
+
'translateZ(' + -sq.width / 2 + 'px) rotateY(' + angle(ri) + 'deg)'
|
|
1469
|
+
"
|
|
1470
|
+
>
|
|
1471
|
+
@for (side of row; track si; let si = $index) {
|
|
1472
|
+
<div
|
|
1473
|
+
class="cs-side"
|
|
1474
|
+
[attr.data-side]="si"
|
|
1475
|
+
[style.grid-template-columns]="'repeat(' + sq.cols + ', minmax(0, 1fr))'"
|
|
1476
|
+
[style.transform]="
|
|
1477
|
+
'rotateY(' + si * 90 + 'deg) translateZ(' + sq.width / 2 + 'px)'
|
|
1478
|
+
"
|
|
1479
|
+
[attr.aria-hidden]="sideOf(ri) === si ? null : 'true'"
|
|
1480
|
+
[attr.inert]="sideOf(ri) === si ? null : ''"
|
|
1481
|
+
>
|
|
1482
|
+
@for (t of side; track ci; let ci = $index) {
|
|
1483
|
+
@if (t !== null) {
|
|
1484
|
+
<div class="cs-cell">
|
|
1485
|
+
@if (tile(); as tpl) {
|
|
1486
|
+
<ng-container
|
|
1487
|
+
[ngTemplateOutlet]="tpl.template"
|
|
1488
|
+
[ngTemplateOutletContext]="{
|
|
1489
|
+
$implicit: t,
|
|
1490
|
+
index: indexOf(t),
|
|
1491
|
+
level: sq.level,
|
|
1492
|
+
cell: sq.cell,
|
|
1493
|
+
rowHeight: sq.rowHeight,
|
|
1494
|
+
list: false,
|
|
1495
|
+
}"
|
|
1496
|
+
/>
|
|
1497
|
+
}
|
|
1498
|
+
</div>
|
|
1499
|
+
} @else if (si < r.sides[ri]) {
|
|
1500
|
+
<div class="cs-place" aria-hidden="true"></div>
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
</div>
|
|
1504
|
+
}
|
|
1505
|
+
</div>
|
|
1506
|
+
</div>
|
|
1507
|
+
}
|
|
1508
|
+
</div>
|
|
1509
|
+
} @else {
|
|
1510
|
+
<div
|
|
1511
|
+
#grid
|
|
1512
|
+
[class]="'cs-square cs-l' + sq.level"
|
|
1513
|
+
[class.cs-list]="sq.list"
|
|
1514
|
+
[class.cs-dashed]="dashed()"
|
|
1515
|
+
[attr.data-level]="sq.level"
|
|
1516
|
+
[style.width.px]="sq.width"
|
|
1517
|
+
[style.height.px]="sq.height"
|
|
1518
|
+
[style.--cs-gap.px]="sq.gap"
|
|
1519
|
+
[style.grid-template-columns]="'repeat(' + sq.cols + ', minmax(0, 1fr))'"
|
|
1520
|
+
[style.grid-template-rows]="'repeat(' + sq.rows + ', minmax(0, 1fr))'"
|
|
1521
|
+
>
|
|
1522
|
+
@for (t of tiles(); track keyOf()(t, $index); let i = $index) {
|
|
1523
|
+
<div class="cs-cell">
|
|
1524
|
+
@if (tile(); as tpl) {
|
|
1525
|
+
<ng-container
|
|
1526
|
+
[ngTemplateOutlet]="tpl.template"
|
|
1527
|
+
[ngTemplateOutletContext]="{
|
|
1528
|
+
$implicit: t,
|
|
1529
|
+
index: i,
|
|
1530
|
+
level: sq.level,
|
|
1531
|
+
cell: sq.cell,
|
|
1532
|
+
rowHeight: sq.rowHeight,
|
|
1533
|
+
list: sq.list,
|
|
1534
|
+
}"
|
|
1535
|
+
/>
|
|
1536
|
+
}
|
|
1537
|
+
</div>
|
|
1538
|
+
}
|
|
1539
|
+
@for (i of openPlaces(); track i) {
|
|
1540
|
+
<div class="cs-place" aria-hidden="true"></div>
|
|
1541
|
+
}
|
|
1542
|
+
</div>
|
|
1543
|
+
}
|
|
1544
|
+
`,
|
|
1545
|
+
isInline: true,
|
|
1546
|
+
styles: [":host{display:block}.cs-square{display:grid;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));--cs-radius: var(--cube-square-radius, 20px)}.cs-cell{display:grid;min-width:0;min-height:0}.cs-place{box-sizing:border-box;border:var(--cube-square-place-width, 1.5px) solid var(--cube-square-place, color-mix(in srgb, #dae0d9 55%, transparent));border-radius:var(--cs-radius)}.cs-dashed .cs-place{border-style:dashed;border-color:var(--cube-square-place-dashed, #dae0d9)}.cs-l0{--cs-radius: 28px}.cs-l2{--cs-radius: 16px}.cs-l3{--cs-radius: 12px}.cs-l4{--cs-radius: 9px}.cs-l4 .cs-place{border-width:1px}.cs-turning{display:flex;flex-direction:column;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));--cs-radius: var(--cube-square-radius, 20px)}.cs-row{position:relative;perspective:1400px;touch-action:pan-y;user-select:none;-webkit-user-select:none;outline:none}.cs-row:focus-visible{outline:2px solid var(--cube-square-focus, #5f9a80);outline-offset:3px;border-radius:var(--cs-radius)}.cs-band{position:absolute;inset:0;transform-style:preserve-3d;transition:transform .38s cubic-bezier(.2,.8,.2,1)}.cs-band.cs-nudging{transition:transform .52s cubic-bezier(.4,0,.2,1)}.cs-band.cs-still{transition:none}.cs-side{position:absolute;inset:0;display:grid;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));backface-visibility:hidden}.cs-edge{pointer-events:none;position:absolute;top:18%;bottom:18%;right:calc(-1*max(4px,var(--cs-gap) - 2px));z-index:1;width:3px;border-radius:999px;background:var(--cube-square-edge, color-mix(in srgb, #5f9a80 45%, transparent))}\n"],
|
|
1547
|
+
dependencies: [{
|
|
1548
|
+
kind: "directive",
|
|
1549
|
+
type: NgTemplateOutlet,
|
|
1550
|
+
selector: "[ngTemplateOutlet]",
|
|
1551
|
+
inputs: [
|
|
1552
|
+
"ngTemplateOutletContext",
|
|
1553
|
+
"ngTemplateOutlet",
|
|
1554
|
+
"ngTemplateOutletInjector"
|
|
1555
|
+
]
|
|
1556
|
+
}],
|
|
1557
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
1558
|
+
});
|
|
1559
|
+
};
|
|
1560
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1561
|
+
minVersion: "12.0.0",
|
|
1562
|
+
version: "22.2.4",
|
|
1563
|
+
ngImport: i0,
|
|
1564
|
+
type: CubeSquare,
|
|
1565
|
+
decorators: [{
|
|
1566
|
+
type: Component,
|
|
1567
|
+
args: [{
|
|
1568
|
+
selector: "cube-square",
|
|
1569
|
+
imports: [NgTemplateOutlet],
|
|
1570
|
+
template: `
|
|
1571
|
+
@let sq = layout();
|
|
1572
|
+
@if (rings(); as r) {
|
|
1573
|
+
<div
|
|
1574
|
+
class="cs-turning"
|
|
1575
|
+
[class]="'cs-turning cs-l' + sq.level"
|
|
1576
|
+
[class.cs-dashed]="dashed()"
|
|
1577
|
+
[attr.data-level]="sq.level"
|
|
1578
|
+
[style.width.px]="sq.width"
|
|
1579
|
+
[style.--cs-gap.px]="sq.gap"
|
|
1580
|
+
>
|
|
1581
|
+
@for (row of r.rows; track ri; let ri = $index) {
|
|
1582
|
+
<div
|
|
1583
|
+
class="cs-row"
|
|
1584
|
+
[class.cs-turns]="r.sides[ri] > 1"
|
|
1585
|
+
[attr.data-row]="ri"
|
|
1586
|
+
[style.height.px]="sq.rowHeight"
|
|
1587
|
+
(pointerdown)="down(ri, $event)"
|
|
1588
|
+
(pointermove)="move(ri, $event)"
|
|
1589
|
+
(pointerup)="up(ri, $event)"
|
|
1590
|
+
(pointercancel)="up(ri, $event)"
|
|
1591
|
+
(keydown)="key(ri, $event)"
|
|
1592
|
+
>
|
|
1593
|
+
@if (r.sides[ri] > 1) {
|
|
1594
|
+
<span class="cs-edge" aria-hidden="true"></span>
|
|
1595
|
+
}
|
|
1596
|
+
<div
|
|
1597
|
+
class="cs-band"
|
|
1598
|
+
[class.cs-still]="dragging() === ri || still()"
|
|
1599
|
+
[class.cs-nudging]="nudging()"
|
|
1600
|
+
[style.transform]="
|
|
1601
|
+
'translateZ(' + -sq.width / 2 + 'px) rotateY(' + angle(ri) + 'deg)'
|
|
1602
|
+
"
|
|
1603
|
+
>
|
|
1604
|
+
@for (side of row; track si; let si = $index) {
|
|
1605
|
+
<div
|
|
1606
|
+
class="cs-side"
|
|
1607
|
+
[attr.data-side]="si"
|
|
1608
|
+
[style.grid-template-columns]="'repeat(' + sq.cols + ', minmax(0, 1fr))'"
|
|
1609
|
+
[style.transform]="
|
|
1610
|
+
'rotateY(' + si * 90 + 'deg) translateZ(' + sq.width / 2 + 'px)'
|
|
1611
|
+
"
|
|
1612
|
+
[attr.aria-hidden]="sideOf(ri) === si ? null : 'true'"
|
|
1613
|
+
[attr.inert]="sideOf(ri) === si ? null : ''"
|
|
1614
|
+
>
|
|
1615
|
+
@for (t of side; track ci; let ci = $index) {
|
|
1616
|
+
@if (t !== null) {
|
|
1617
|
+
<div class="cs-cell">
|
|
1618
|
+
@if (tile(); as tpl) {
|
|
1619
|
+
<ng-container
|
|
1620
|
+
[ngTemplateOutlet]="tpl.template"
|
|
1621
|
+
[ngTemplateOutletContext]="{
|
|
1622
|
+
$implicit: t,
|
|
1623
|
+
index: indexOf(t),
|
|
1624
|
+
level: sq.level,
|
|
1625
|
+
cell: sq.cell,
|
|
1626
|
+
rowHeight: sq.rowHeight,
|
|
1627
|
+
list: false,
|
|
1628
|
+
}"
|
|
1629
|
+
/>
|
|
1630
|
+
}
|
|
1631
|
+
</div>
|
|
1632
|
+
} @else if (si < r.sides[ri]) {
|
|
1633
|
+
<div class="cs-place" aria-hidden="true"></div>
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
</div>
|
|
1637
|
+
}
|
|
1638
|
+
</div>
|
|
1639
|
+
</div>
|
|
1640
|
+
}
|
|
1641
|
+
</div>
|
|
1642
|
+
} @else {
|
|
1643
|
+
<div
|
|
1644
|
+
#grid
|
|
1645
|
+
[class]="'cs-square cs-l' + sq.level"
|
|
1646
|
+
[class.cs-list]="sq.list"
|
|
1647
|
+
[class.cs-dashed]="dashed()"
|
|
1648
|
+
[attr.data-level]="sq.level"
|
|
1649
|
+
[style.width.px]="sq.width"
|
|
1650
|
+
[style.height.px]="sq.height"
|
|
1651
|
+
[style.--cs-gap.px]="sq.gap"
|
|
1652
|
+
[style.grid-template-columns]="'repeat(' + sq.cols + ', minmax(0, 1fr))'"
|
|
1653
|
+
[style.grid-template-rows]="'repeat(' + sq.rows + ', minmax(0, 1fr))'"
|
|
1654
|
+
>
|
|
1655
|
+
@for (t of tiles(); track keyOf()(t, $index); let i = $index) {
|
|
1656
|
+
<div class="cs-cell">
|
|
1657
|
+
@if (tile(); as tpl) {
|
|
1658
|
+
<ng-container
|
|
1659
|
+
[ngTemplateOutlet]="tpl.template"
|
|
1660
|
+
[ngTemplateOutletContext]="{
|
|
1661
|
+
$implicit: t,
|
|
1662
|
+
index: i,
|
|
1663
|
+
level: sq.level,
|
|
1664
|
+
cell: sq.cell,
|
|
1665
|
+
rowHeight: sq.rowHeight,
|
|
1666
|
+
list: sq.list,
|
|
1667
|
+
}"
|
|
1668
|
+
/>
|
|
1669
|
+
}
|
|
1670
|
+
</div>
|
|
1671
|
+
}
|
|
1672
|
+
@for (i of openPlaces(); track i) {
|
|
1673
|
+
<div class="cs-place" aria-hidden="true"></div>
|
|
1674
|
+
}
|
|
1675
|
+
</div>
|
|
1676
|
+
}
|
|
1677
|
+
`,
|
|
1678
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1679
|
+
styles: [":host{display:block}.cs-square{display:grid;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));--cs-radius: var(--cube-square-radius, 20px)}.cs-cell{display:grid;min-width:0;min-height:0}.cs-place{box-sizing:border-box;border:var(--cube-square-place-width, 1.5px) solid var(--cube-square-place, color-mix(in srgb, #dae0d9 55%, transparent));border-radius:var(--cs-radius)}.cs-dashed .cs-place{border-style:dashed;border-color:var(--cube-square-place-dashed, #dae0d9)}.cs-l0{--cs-radius: 28px}.cs-l2{--cs-radius: 16px}.cs-l3{--cs-radius: 12px}.cs-l4{--cs-radius: 9px}.cs-l4 .cs-place{border-width:1px}.cs-turning{display:flex;flex-direction:column;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));--cs-radius: var(--cube-square-radius, 20px)}.cs-row{position:relative;perspective:1400px;touch-action:pan-y;user-select:none;-webkit-user-select:none;outline:none}.cs-row:focus-visible{outline:2px solid var(--cube-square-focus, #5f9a80);outline-offset:3px;border-radius:var(--cs-radius)}.cs-band{position:absolute;inset:0;transform-style:preserve-3d;transition:transform .38s cubic-bezier(.2,.8,.2,1)}.cs-band.cs-nudging{transition:transform .52s cubic-bezier(.4,0,.2,1)}.cs-band.cs-still{transition:none}.cs-side{position:absolute;inset:0;display:grid;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));backface-visibility:hidden}.cs-edge{pointer-events:none;position:absolute;top:18%;bottom:18%;right:calc(-1*max(4px,var(--cs-gap) - 2px));z-index:1;width:3px;border-radius:999px;background:var(--cube-square-edge, color-mix(in srgb, #5f9a80 45%, transparent))}\n"]
|
|
1680
|
+
}]
|
|
1681
|
+
}],
|
|
1682
|
+
ctorParameters: () => [],
|
|
1683
|
+
propDecorators: {
|
|
1684
|
+
tiles: [{
|
|
1685
|
+
type: i0.Input,
|
|
1686
|
+
args: [{
|
|
1687
|
+
isSignal: true,
|
|
1688
|
+
alias: "tiles",
|
|
1689
|
+
required: true
|
|
1690
|
+
}]
|
|
1691
|
+
}],
|
|
1692
|
+
view: [{
|
|
1693
|
+
type: i0.Input,
|
|
1694
|
+
args: [{
|
|
1695
|
+
isSignal: true,
|
|
1696
|
+
alias: "view",
|
|
1697
|
+
required: false
|
|
1698
|
+
}]
|
|
1699
|
+
}],
|
|
1700
|
+
maxSide: [{
|
|
1701
|
+
type: i0.Input,
|
|
1702
|
+
args: [{
|
|
1703
|
+
isSignal: true,
|
|
1704
|
+
alias: "maxSide",
|
|
1705
|
+
required: false
|
|
1706
|
+
}]
|
|
1707
|
+
}],
|
|
1708
|
+
listRow: [{
|
|
1709
|
+
type: i0.Input,
|
|
1710
|
+
args: [{
|
|
1711
|
+
isSignal: true,
|
|
1712
|
+
alias: "listRow",
|
|
1713
|
+
required: false
|
|
1714
|
+
}]
|
|
1715
|
+
}],
|
|
1716
|
+
dashed: [{
|
|
1717
|
+
type: i0.Input,
|
|
1718
|
+
args: [{
|
|
1719
|
+
isSignal: true,
|
|
1720
|
+
alias: "dashed",
|
|
1721
|
+
required: false
|
|
1722
|
+
}]
|
|
1723
|
+
}],
|
|
1724
|
+
keyOf: [{
|
|
1725
|
+
type: i0.Input,
|
|
1726
|
+
args: [{
|
|
1727
|
+
isSignal: true,
|
|
1728
|
+
alias: "keyOf",
|
|
1729
|
+
required: false
|
|
1730
|
+
}]
|
|
1731
|
+
}],
|
|
1732
|
+
turning: [{
|
|
1733
|
+
type: i0.Input,
|
|
1734
|
+
args: [{
|
|
1735
|
+
isSignal: true,
|
|
1736
|
+
alias: "turning",
|
|
1737
|
+
required: false
|
|
1738
|
+
}]
|
|
1739
|
+
}],
|
|
1740
|
+
turnBelow: [{
|
|
1741
|
+
type: i0.Input,
|
|
1742
|
+
args: [{
|
|
1743
|
+
isSignal: true,
|
|
1744
|
+
alias: "turnBelow",
|
|
1745
|
+
required: false
|
|
1746
|
+
}]
|
|
1747
|
+
}],
|
|
1748
|
+
across: [{
|
|
1749
|
+
type: i0.Input,
|
|
1750
|
+
args: [{
|
|
1751
|
+
isSignal: true,
|
|
1752
|
+
alias: "across",
|
|
1753
|
+
required: false
|
|
1754
|
+
}]
|
|
1755
|
+
}],
|
|
1756
|
+
isOwn: [{
|
|
1757
|
+
type: i0.Input,
|
|
1758
|
+
args: [{
|
|
1759
|
+
isSignal: true,
|
|
1760
|
+
alias: "isOwn",
|
|
1761
|
+
required: false
|
|
1762
|
+
}]
|
|
1763
|
+
}],
|
|
1764
|
+
nudgeKey: [{
|
|
1765
|
+
type: i0.Input,
|
|
1766
|
+
args: [{
|
|
1767
|
+
isSignal: true,
|
|
1768
|
+
alias: "nudgeKey",
|
|
1769
|
+
required: false
|
|
1770
|
+
}]
|
|
1771
|
+
}],
|
|
1772
|
+
tile: [{
|
|
1773
|
+
type: i0.ContentChild,
|
|
1774
|
+
args: [i0.forwardRef(() => CubeSquareTile), { isSignal: true }]
|
|
1775
|
+
}],
|
|
1776
|
+
grid: [{
|
|
1777
|
+
type: i0.ViewChild,
|
|
1778
|
+
args: ["grid", { isSignal: true }]
|
|
1779
|
+
}]
|
|
1780
|
+
}
|
|
1781
|
+
});
|
|
1782
|
+
const contextLevelFor = squareLevelFor;
|
|
1783
|
+
function contextSquare(count, room, maxSide = 880) {
|
|
1784
|
+
const { cols: n, rows } = gridFor("square", count);
|
|
1785
|
+
const side = Math.max(0, Math.min(room, maxSide));
|
|
1786
|
+
const gap = squareGap(n);
|
|
1787
|
+
const cell = (side - gap * (n - 1)) / n;
|
|
1788
|
+
return {
|
|
1789
|
+
n,
|
|
1790
|
+
side,
|
|
1791
|
+
gap,
|
|
1792
|
+
level: contextLevelFor(cell),
|
|
1793
|
+
open: n * rows - Math.max(0, count)
|
|
1794
|
+
};
|
|
1795
|
+
}
|
|
1796
|
+
function contextIcon(tile) {
|
|
1797
|
+
if (CUBE_ICON_NAMES.includes(tile.icon)) return tile.icon;
|
|
1798
|
+
if (tile.adds) return "plus";
|
|
1799
|
+
if (tile.icon === "hide") return "shown";
|
|
1800
|
+
return "face";
|
|
1801
|
+
}
|
|
1802
|
+
var CubeContext = class CubeContext {
|
|
1803
|
+
held = input.required(...ngDevMode ? [{ debugName: "held" }] : /* istanbul ignore next */ []);
|
|
1804
|
+
path = input([], ...ngDevMode ? [{ debugName: "path" }] : /* istanbul ignore next */ []);
|
|
1805
|
+
source = input(null, ...ngDevMode ? [{ debugName: "source" }] : /* istanbul ignore next */ []);
|
|
1806
|
+
words = input(null, ...ngDevMode ? [{ debugName: "words" }] : /* istanbul ignore next */ []);
|
|
1807
|
+
maxSide = input(880, ...ngDevMode ? [{ debugName: "maxSide" }] : /* istanbul ignore next */ []);
|
|
1808
|
+
enter = output();
|
|
1809
|
+
out = output();
|
|
1810
|
+
done = output();
|
|
1811
|
+
tapped = output();
|
|
1812
|
+
given = inject(CONTEXT_CUBE_SOURCE, { optional: true });
|
|
1813
|
+
givenWords = inject(CONTEXT_CUBE_WORDS, { optional: true });
|
|
1814
|
+
busy = signal(null, ...ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []);
|
|
1815
|
+
again = signal(0, ...ngDevMode ? [{ debugName: "again" }] : /* istanbul ignore next */ []);
|
|
1816
|
+
from = computed(() => {
|
|
1817
|
+
const s = this.source() ?? this.given;
|
|
1818
|
+
if (!s) throw new Error("cube-context: provide CONTEXT_CUBE_SOURCE or pass [source]");
|
|
1819
|
+
return s;
|
|
1820
|
+
}, ...ngDevMode ? [{ debugName: "from" }] : /* istanbul ignore next */ []);
|
|
1821
|
+
where = computed(() => this.path().join("\0"), ...ngDevMode ? [{ debugName: "where" }] : /* istanbul ignore next */ []);
|
|
1822
|
+
level = computed(() => {
|
|
1823
|
+
this.again();
|
|
1824
|
+
return this.from().level(this.held(), this.path());
|
|
1825
|
+
}, ...ngDevMode ? [{ debugName: "level" }] : /* istanbul ignore next */ []);
|
|
1826
|
+
tiles = computed(() => this.level() ?? [], ...ngDevMode ? [{ debugName: "tiles" }] : /* istanbul ignore next */ []);
|
|
1827
|
+
adds = computed(() => this.tiles().some((t) => !!t.adds), ...ngDevMode ? [{ debugName: "adds" }] : /* istanbul ignore next */ []);
|
|
1828
|
+
keyOf = (t) => t.key;
|
|
1829
|
+
inUseWord = computed(() => (this.words() ?? this.givenWords)?.inUse ?? null, ...ngDevMode ? [{ debugName: "inUseWord" }] : /* istanbul ignore next */ []);
|
|
1830
|
+
iconOf = contextIcon;
|
|
1831
|
+
constructor() {
|
|
1832
|
+
effect(() => {
|
|
1833
|
+
if (this.level() === null) untracked(() => this.out.emit());
|
|
1834
|
+
});
|
|
1835
|
+
effect(() => {
|
|
1836
|
+
this.where();
|
|
1837
|
+
this.held();
|
|
1838
|
+
untracked(() => this.busy.set(null));
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
async tap(tile, element) {
|
|
1842
|
+
if (this.busy() !== null) return;
|
|
1843
|
+
if (element) this.tapped.emit({
|
|
1844
|
+
tile,
|
|
1845
|
+
element
|
|
1846
|
+
});
|
|
1847
|
+
const held = this.held();
|
|
1848
|
+
const path = this.path();
|
|
1849
|
+
const where = this.where();
|
|
1850
|
+
const here = () => this.held() === held && this.where() === where;
|
|
1851
|
+
this.busy.set(tile.key);
|
|
1852
|
+
try {
|
|
1853
|
+
const picked = await this.from().pick(held, path, tile);
|
|
1854
|
+
if (!here()) return;
|
|
1855
|
+
switch (picked.kind) {
|
|
1856
|
+
case "enter":
|
|
1857
|
+
this.enter.emit(picked.path);
|
|
1858
|
+
break;
|
|
1859
|
+
case "done":
|
|
1860
|
+
this.done.emit(tile);
|
|
1861
|
+
break;
|
|
1862
|
+
case "out": this.out.emit();
|
|
1863
|
+
}
|
|
1864
|
+
} finally {
|
|
1865
|
+
if (here()) this.busy.set(null);
|
|
1866
|
+
this.again.update((n) => n + 1);
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1870
|
+
minVersion: "12.0.0",
|
|
1871
|
+
version: "22.2.4",
|
|
1872
|
+
ngImport: i0,
|
|
1873
|
+
type: CubeContext,
|
|
1874
|
+
deps: [],
|
|
1875
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
1876
|
+
});
|
|
1877
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
1878
|
+
minVersion: "17.0.0",
|
|
1879
|
+
version: "22.2.4",
|
|
1880
|
+
type: CubeContext,
|
|
1881
|
+
isStandalone: true,
|
|
1882
|
+
selector: "cube-context",
|
|
1883
|
+
inputs: {
|
|
1884
|
+
held: {
|
|
1885
|
+
classPropertyName: "held",
|
|
1886
|
+
publicName: "held",
|
|
1887
|
+
isSignal: true,
|
|
1888
|
+
isRequired: true,
|
|
1889
|
+
transformFunction: null
|
|
1890
|
+
},
|
|
1891
|
+
path: {
|
|
1892
|
+
classPropertyName: "path",
|
|
1893
|
+
publicName: "path",
|
|
1894
|
+
isSignal: true,
|
|
1895
|
+
isRequired: false,
|
|
1896
|
+
transformFunction: null
|
|
1897
|
+
},
|
|
1898
|
+
source: {
|
|
1899
|
+
classPropertyName: "source",
|
|
1900
|
+
publicName: "source",
|
|
1901
|
+
isSignal: true,
|
|
1902
|
+
isRequired: false,
|
|
1903
|
+
transformFunction: null
|
|
1904
|
+
},
|
|
1905
|
+
words: {
|
|
1906
|
+
classPropertyName: "words",
|
|
1907
|
+
publicName: "words",
|
|
1908
|
+
isSignal: true,
|
|
1909
|
+
isRequired: false,
|
|
1910
|
+
transformFunction: null
|
|
1911
|
+
},
|
|
1912
|
+
maxSide: {
|
|
1913
|
+
classPropertyName: "maxSide",
|
|
1914
|
+
publicName: "maxSide",
|
|
1915
|
+
isSignal: true,
|
|
1916
|
+
isRequired: false,
|
|
1917
|
+
transformFunction: null
|
|
1918
|
+
}
|
|
1919
|
+
},
|
|
1920
|
+
outputs: {
|
|
1921
|
+
enter: "enter",
|
|
1922
|
+
out: "out",
|
|
1923
|
+
done: "done",
|
|
1924
|
+
tapped: "tapped"
|
|
1925
|
+
},
|
|
1926
|
+
ngImport: i0,
|
|
1927
|
+
template: `
|
|
1928
|
+
<cube-square
|
|
1929
|
+
[tiles]="tiles()"
|
|
1930
|
+
[dashed]="adds()"
|
|
1931
|
+
[maxSide]="maxSide()"
|
|
1932
|
+
[keyOf]="keyOf"
|
|
1933
|
+
[class.cc-adds]="adds()"
|
|
1934
|
+
>
|
|
1935
|
+
<ng-template [cubeSquareTile]="tiles()" let-t let-level="level">
|
|
1936
|
+
<button
|
|
1937
|
+
type="button"
|
|
1938
|
+
[class]="'cc-tile cc-l' + level"
|
|
1939
|
+
[class.cc-in-use]="!!t.inUse"
|
|
1940
|
+
[class.cc-pale]="!!t.pale"
|
|
1941
|
+
[class.cc-adds]="!!t.adds"
|
|
1942
|
+
[class.cc-busy]="busy() === t.key"
|
|
1943
|
+
[disabled]="busy() !== null"
|
|
1944
|
+
[attr.aria-label]="level >= 4 ? t.title : null"
|
|
1945
|
+
[attr.aria-current]="t.inUse ? 'true' : null"
|
|
1946
|
+
[attr.title]="level >= 3 ? t.title : null"
|
|
1947
|
+
(click)="tap(t, $any($event.currentTarget))"
|
|
1948
|
+
>
|
|
1949
|
+
<span class="cc-icon"><cube-icon [icon]="iconOf(t)" [inUse]="!!t.inUse" /></span>
|
|
1950
|
+
@if (level < 4) {
|
|
1951
|
+
<span class="cc-t">{{ t.title }}</span>
|
|
1952
|
+
}
|
|
1953
|
+
@if (t.line && level < 3) {
|
|
1954
|
+
<span class="cc-m">{{ t.line }}</span>
|
|
1955
|
+
}
|
|
1956
|
+
@if (t.inUse && inUseWord() && level < 3) {
|
|
1957
|
+
<span class="cc-tick">{{ inUseWord() }}</span>
|
|
1958
|
+
}
|
|
1959
|
+
</button>
|
|
1960
|
+
</ng-template>
|
|
1961
|
+
</cube-square>
|
|
1962
|
+
`,
|
|
1963
|
+
isInline: true,
|
|
1964
|
+
styles: [":host{display:block;font:inherit;color:var(--cube-context-ink, #1f2a26);--cube-square-place: color-mix(in srgb, var(--cube-context-line, #dae0d9) 55%, transparent);--cube-square-place-dashed: var(--cube-context-line, #dae0d9);--cube-square-radius: var(--cube-context-radius, 20px)}.cc-tile{all:unset;cursor:pointer;box-sizing:border-box;min-width:0;min-height:0;height:100%;overflow:hidden;display:grid;justify-items:center;align-content:center;gap:6px;padding:14px 10px 12px;text-align:center;background:var(--cube-context-tile, #ffffff);border:1px solid var(--cube-context-line, #dae0d9);border-radius:var(--cube-context-radius, 20px);user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:transform .16s}.cc-tile:active:not(:disabled){transform:scale(.97)}.cc-tile:focus-visible{outline:3px solid var(--cube-context-focus, #5f9a80);outline-offset:2px}.cc-tile.cc-in-use{border:2px solid var(--cube-context-in-use, #3b5a4c)}.cc-tile.cc-pale{background:transparent;border:2px dashed var(--cube-context-line, #dae0d9);color:var(--cube-context-quiet, #5d6a64)}.cc-tile.cc-adds{border:2px solid var(--cube-context-adds, #c8693f)}.cc-tile.cc-busy{opacity:.6;cursor:progress}.cc-tile:disabled:not(.cc-busy){cursor:default}.cc-icon{display:grid;place-items:center;line-height:0}.cc-tile.cc-adds .cc-icon{width:52px;height:52px;border-radius:50%;background:var(--cube-context-adds-bg, #f3e3d6);--cube-icon-stroke: var(--cube-context-adds-ink, #7a4a2b);--cube-icon-size: 26px}.cc-t,.cc-m{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere}.cc-t{font-size:17px;font-weight:700;line-height:1.2}.cc-m{font-size:13px;line-height:1.3;color:var(--cube-context-quiet, #5d6a64)}.cc-tick{font-size:13px;font-weight:800;color:var(--cube-context-in-use, #3b5a4c)}.cc-tile.cc-l0{border-radius:28px;padding:24px;gap:10px}.cc-l0 .cc-t{font-size:26px}.cc-l0 .cc-m{font-size:16px}.cc-l0 .cc-icon{--cube-icon-size: 64px}.cc-tile.cc-l0.cc-adds .cc-icon{width:96px;height:96px;--cube-icon-size: 40px}.cc-tile.cc-l2{border-radius:16px;padding:10px 6px;gap:5px}.cc-l2 .cc-t{font-size:14px}.cc-l2 .cc-m{font-size:12px}.cc-tile.cc-l3{border-radius:12px;padding:6px 4px;gap:3px}.cc-l3 .cc-t{font-size:12px}.cc-tile.cc-l4{border-radius:9px;padding:2px;gap:0}.cc-l3 .cc-icon,.cc-l4 .cc-icon{--cube-icon-size: 24px}.cc-tile.cc-l3.cc-adds .cc-icon,.cc-tile.cc-l4.cc-adds .cc-icon{width:30px;height:30px;--cube-icon-size: 18px}\n"],
|
|
1965
|
+
dependencies: [
|
|
1966
|
+
{
|
|
1967
|
+
kind: "component",
|
|
1968
|
+
type: CubeIcon,
|
|
1969
|
+
selector: "cube-icon",
|
|
1970
|
+
inputs: ["icon", "inUse"]
|
|
1971
|
+
},
|
|
1972
|
+
{
|
|
1973
|
+
kind: "component",
|
|
1974
|
+
type: CubeSquare,
|
|
1975
|
+
selector: "cube-square",
|
|
1976
|
+
inputs: [
|
|
1977
|
+
"tiles",
|
|
1978
|
+
"view",
|
|
1979
|
+
"maxSide",
|
|
1980
|
+
"listRow",
|
|
1981
|
+
"dashed",
|
|
1982
|
+
"keyOf",
|
|
1983
|
+
"turning",
|
|
1984
|
+
"turnBelow",
|
|
1985
|
+
"across",
|
|
1986
|
+
"isOwn",
|
|
1987
|
+
"nudgeKey"
|
|
1988
|
+
]
|
|
1989
|
+
},
|
|
1990
|
+
{
|
|
1991
|
+
kind: "directive",
|
|
1992
|
+
type: CubeSquareTile,
|
|
1993
|
+
selector: "ng-template[cubeSquareTile]",
|
|
1994
|
+
inputs: ["cubeSquareTile"]
|
|
1995
|
+
}
|
|
1996
|
+
],
|
|
1997
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
1998
|
+
});
|
|
1999
|
+
};
|
|
2000
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
2001
|
+
minVersion: "12.0.0",
|
|
2002
|
+
version: "22.2.4",
|
|
2003
|
+
ngImport: i0,
|
|
2004
|
+
type: CubeContext,
|
|
2005
|
+
decorators: [{
|
|
2006
|
+
type: Component,
|
|
2007
|
+
args: [{
|
|
2008
|
+
selector: "cube-context",
|
|
2009
|
+
imports: [
|
|
2010
|
+
CubeIcon,
|
|
2011
|
+
CubeSquare,
|
|
2012
|
+
CubeSquareTile
|
|
2013
|
+
],
|
|
2014
|
+
template: `
|
|
2015
|
+
<cube-square
|
|
2016
|
+
[tiles]="tiles()"
|
|
2017
|
+
[dashed]="adds()"
|
|
2018
|
+
[maxSide]="maxSide()"
|
|
2019
|
+
[keyOf]="keyOf"
|
|
2020
|
+
[class.cc-adds]="adds()"
|
|
2021
|
+
>
|
|
2022
|
+
<ng-template [cubeSquareTile]="tiles()" let-t let-level="level">
|
|
2023
|
+
<button
|
|
2024
|
+
type="button"
|
|
2025
|
+
[class]="'cc-tile cc-l' + level"
|
|
2026
|
+
[class.cc-in-use]="!!t.inUse"
|
|
2027
|
+
[class.cc-pale]="!!t.pale"
|
|
2028
|
+
[class.cc-adds]="!!t.adds"
|
|
2029
|
+
[class.cc-busy]="busy() === t.key"
|
|
2030
|
+
[disabled]="busy() !== null"
|
|
2031
|
+
[attr.aria-label]="level >= 4 ? t.title : null"
|
|
2032
|
+
[attr.aria-current]="t.inUse ? 'true' : null"
|
|
2033
|
+
[attr.title]="level >= 3 ? t.title : null"
|
|
2034
|
+
(click)="tap(t, $any($event.currentTarget))"
|
|
2035
|
+
>
|
|
2036
|
+
<span class="cc-icon"><cube-icon [icon]="iconOf(t)" [inUse]="!!t.inUse" /></span>
|
|
2037
|
+
@if (level < 4) {
|
|
2038
|
+
<span class="cc-t">{{ t.title }}</span>
|
|
2039
|
+
}
|
|
2040
|
+
@if (t.line && level < 3) {
|
|
2041
|
+
<span class="cc-m">{{ t.line }}</span>
|
|
2042
|
+
}
|
|
2043
|
+
@if (t.inUse && inUseWord() && level < 3) {
|
|
2044
|
+
<span class="cc-tick">{{ inUseWord() }}</span>
|
|
2045
|
+
}
|
|
2046
|
+
</button>
|
|
2047
|
+
</ng-template>
|
|
2048
|
+
</cube-square>
|
|
2049
|
+
`,
|
|
2050
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2051
|
+
styles: [":host{display:block;font:inherit;color:var(--cube-context-ink, #1f2a26);--cube-square-place: color-mix(in srgb, var(--cube-context-line, #dae0d9) 55%, transparent);--cube-square-place-dashed: var(--cube-context-line, #dae0d9);--cube-square-radius: var(--cube-context-radius, 20px)}.cc-tile{all:unset;cursor:pointer;box-sizing:border-box;min-width:0;min-height:0;height:100%;overflow:hidden;display:grid;justify-items:center;align-content:center;gap:6px;padding:14px 10px 12px;text-align:center;background:var(--cube-context-tile, #ffffff);border:1px solid var(--cube-context-line, #dae0d9);border-radius:var(--cube-context-radius, 20px);user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:transform .16s}.cc-tile:active:not(:disabled){transform:scale(.97)}.cc-tile:focus-visible{outline:3px solid var(--cube-context-focus, #5f9a80);outline-offset:2px}.cc-tile.cc-in-use{border:2px solid var(--cube-context-in-use, #3b5a4c)}.cc-tile.cc-pale{background:transparent;border:2px dashed var(--cube-context-line, #dae0d9);color:var(--cube-context-quiet, #5d6a64)}.cc-tile.cc-adds{border:2px solid var(--cube-context-adds, #c8693f)}.cc-tile.cc-busy{opacity:.6;cursor:progress}.cc-tile:disabled:not(.cc-busy){cursor:default}.cc-icon{display:grid;place-items:center;line-height:0}.cc-tile.cc-adds .cc-icon{width:52px;height:52px;border-radius:50%;background:var(--cube-context-adds-bg, #f3e3d6);--cube-icon-stroke: var(--cube-context-adds-ink, #7a4a2b);--cube-icon-size: 26px}.cc-t,.cc-m{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere}.cc-t{font-size:17px;font-weight:700;line-height:1.2}.cc-m{font-size:13px;line-height:1.3;color:var(--cube-context-quiet, #5d6a64)}.cc-tick{font-size:13px;font-weight:800;color:var(--cube-context-in-use, #3b5a4c)}.cc-tile.cc-l0{border-radius:28px;padding:24px;gap:10px}.cc-l0 .cc-t{font-size:26px}.cc-l0 .cc-m{font-size:16px}.cc-l0 .cc-icon{--cube-icon-size: 64px}.cc-tile.cc-l0.cc-adds .cc-icon{width:96px;height:96px;--cube-icon-size: 40px}.cc-tile.cc-l2{border-radius:16px;padding:10px 6px;gap:5px}.cc-l2 .cc-t{font-size:14px}.cc-l2 .cc-m{font-size:12px}.cc-tile.cc-l3{border-radius:12px;padding:6px 4px;gap:3px}.cc-l3 .cc-t{font-size:12px}.cc-tile.cc-l4{border-radius:9px;padding:2px;gap:0}.cc-l3 .cc-icon,.cc-l4 .cc-icon{--cube-icon-size: 24px}.cc-tile.cc-l3.cc-adds .cc-icon,.cc-tile.cc-l4.cc-adds .cc-icon{width:30px;height:30px;--cube-icon-size: 18px}\n"]
|
|
2052
|
+
}]
|
|
2053
|
+
}],
|
|
2054
|
+
ctorParameters: () => [],
|
|
2055
|
+
propDecorators: {
|
|
2056
|
+
held: [{
|
|
2057
|
+
type: i0.Input,
|
|
2058
|
+
args: [{
|
|
2059
|
+
isSignal: true,
|
|
2060
|
+
alias: "held",
|
|
2061
|
+
required: true
|
|
2062
|
+
}]
|
|
2063
|
+
}],
|
|
2064
|
+
path: [{
|
|
2065
|
+
type: i0.Input,
|
|
2066
|
+
args: [{
|
|
2067
|
+
isSignal: true,
|
|
2068
|
+
alias: "path",
|
|
2069
|
+
required: false
|
|
2070
|
+
}]
|
|
2071
|
+
}],
|
|
2072
|
+
source: [{
|
|
2073
|
+
type: i0.Input,
|
|
2074
|
+
args: [{
|
|
2075
|
+
isSignal: true,
|
|
2076
|
+
alias: "source",
|
|
2077
|
+
required: false
|
|
2078
|
+
}]
|
|
2079
|
+
}],
|
|
2080
|
+
words: [{
|
|
2081
|
+
type: i0.Input,
|
|
2082
|
+
args: [{
|
|
2083
|
+
isSignal: true,
|
|
2084
|
+
alias: "words",
|
|
2085
|
+
required: false
|
|
2086
|
+
}]
|
|
2087
|
+
}],
|
|
2088
|
+
maxSide: [{
|
|
2089
|
+
type: i0.Input,
|
|
2090
|
+
args: [{
|
|
2091
|
+
isSignal: true,
|
|
2092
|
+
alias: "maxSide",
|
|
2093
|
+
required: false
|
|
2094
|
+
}]
|
|
2095
|
+
}],
|
|
2096
|
+
enter: [{
|
|
2097
|
+
type: i0.Output,
|
|
2098
|
+
args: ["enter"]
|
|
2099
|
+
}],
|
|
2100
|
+
out: [{
|
|
2101
|
+
type: i0.Output,
|
|
2102
|
+
args: ["out"]
|
|
2103
|
+
}],
|
|
2104
|
+
done: [{
|
|
2105
|
+
type: i0.Output,
|
|
2106
|
+
args: ["done"]
|
|
2107
|
+
}],
|
|
2108
|
+
tapped: [{
|
|
2109
|
+
type: i0.Output,
|
|
2110
|
+
args: ["tapped"]
|
|
2111
|
+
}]
|
|
2112
|
+
}
|
|
2113
|
+
});
|
|
2114
|
+
export { CONTEXT_CUBE_SOURCE, CONTEXT_CUBE_WORDS, CONTEXT_PART_ORDER, CUBE_HOLD_MS, CUBE_HOLD_SLOP, CUBE_ICON_NAMES, CubeContext, CubeHold, CubeIcon, CubePicture, CubeSquare, CubeSquareTile, PART_ICONS, SQUARE_LIST_ROW, SQUARE_MAX_SIDE, TURNING_BELOW, TURNING_NUDGE_UNTIL, TURNING_SIDES, VIEW_KEYS, contextIcon, contextLevelFor, contextSquare, cubeIconCells, directionWords, drawCube, gridFor, hideLevel, isView, namesLevel, orderParts, partsLevel, sizeFor, sortDirectionsLevel, sortItems, sortLevel, squareGap, squareLayout, squareLevelFor, turningFront, turningRows, viewLevel };
|
|
2115
|
+
|
|
2116
|
+
//# sourceMappingURL=selimssevgi-cube-design-angular.mjs.map
|