@selimssevgi/cube-design-angular 0.3.0 → 0.5.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
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
nothing yet.
|
|
6
6
|
|
|
7
|
+
## 0.5.0 (4 november 2026: released so mosaic's home grouped my way brings things in and keeps my own order)
|
|
8
|
+
|
|
9
|
+
- **bring things in**, `bringOf(source, into, { at, pieces })` and `bringLevel` (`CubeBring`, `BringOptions`, `BringWords`): where turned round (the study `studies/bringing-things-in.md`, way b, picked by selim on 4 november 2026). where lists places for one piece; bring lists pieces for one place: what stands in `at` (the top by default), each ticked when it is in already, the place itself and a piece holding it pale, a › on a piece with something to bring inside it, what a tap asks (`stand`, `take-out`) and why it would be refused, over the same `WhereSource`. `pieces` lists the app's own (lately) instead. from mosaic's grouping prototype (`bring-things-in.html`).
|
|
10
|
+
- **my own order**, `moveBefore(order, piece, before, { fixedFirst })`, `orderOf` and `orderLevel` (`CubeOrderPlace`, `OrderWords`, `OrderRefusal`, `MINE_SORT`): the person orders a place's pieces by hand; the order is the place's, never the piece's, and a fixed first piece the app names (mosaic's apps at its top) stays first. the level is the place's pieces as they come, the held one ticked, a tap puts it before another, **last** at the end.
|
|
11
|
+
- **add as a level**, `addLevel(ways)` (`AddWay`): the app's ways to add to a place as context tiles, the plus last (selim: bring things in first, then the plus with a short line). what add holds is each app's, and may differ from place to place.
|
|
12
|
+
- `ContextPartKey` and `CONTEXT_PART_ORDER` know `bring` (after change) and `order` (after sort), drawn as move and sort (`PART_ICONS`). an app that uses neither sees no change.
|
|
13
|
+
|
|
14
|
+
## 0.4.0 (4 november 2026: released so mosaic's home grouped my way draws its context cube with `<cube-context>`)
|
|
15
|
+
|
|
16
|
+
- `ContextTile.attrs`: the app's own `data-*` attributes on a tile's cell (`cc-cell`, which holds the tile and its ›), so a test or a use-case runner finds the context cube's tiles by the app's own handles (`data-name`, `data-kind`, `data-ticked`). only `data-*` names are set, a null leaves one out, and one a later tile no longer gives is taken off. found moving mosaic's home grouped my way onto `<cube-context>` (4 november 2026): it drew its context cube with its own square only to carry the runner's handles, and so it had no view (selim: "whenever there is a solution in the library, we should make use of it").
|
|
17
|
+
|
|
7
18
|
## 0.3.0 (3 november 2026: released so cubes, anlat and mosaic take the pinch and the loading look; selim, "the rest can be done")
|
|
8
19
|
|
|
9
20
|
- **on its way**, `<cube-loading>` (`CubeLoading`, `CubeLoadingWay`, `CUBE_LOADING_WAYS`, `CubeLoadingLevel`, `CUBE_LOADING_LEVELS`, `loadingWayFor`, `loadingStickers`, `stillStep`, `CUBE_LOADING_STEP_MS`, `CUBE_LOADING_WIDTH`, `CUBE_LOADING_COLOURS`, `CUBE_LOADING_STICKERS`): something on its way, the cube design way (selim's decision of 3 november 2026, the study `studies/loading-pieces.md`, finding G3). a page or a cube shows the picture's pale stickers taking colour one by one (`fill`), with the square's places pale below on a page; a piece (a tile, a button saving) shows a small cube whose colours turn round its stickers (`turn`), in place of a ring. `level` (`page`, `cube`, `piece`), `way` (null is the level's), `count`, `colours`, `width`, and `failed`: the picture rests pale, never red, beside the app's own retry (`[cubeLoadingRetry]`). no words: the app projects its line. `prefers-reduced-motion` stops it; `aria-busy` and a polite live line. `--cube-loading-place` and `--cube-loading-gap` in both token files. the places wait and the cube grows stay options to add.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, InjectionToken, PLATFORM_ID, TemplateRef, afterNextRender, computed, contentChild, effect, inject, input, output, signal, untracked, viewChild } from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, InjectionToken, PLATFORM_ID, Renderer2, TemplateRef, afterNextRender, computed, contentChild, effect, inject, input, output, signal, untracked, viewChild } from "@angular/core";
|
|
3
3
|
import { NgTemplateOutlet, isPlatformBrowser } from "@angular/common";
|
|
4
4
|
function sizeFor(count) {
|
|
5
5
|
let s = 1;
|
|
@@ -1417,8 +1417,10 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1417
1417
|
const CONTEXT_PART_ORDER = [
|
|
1418
1418
|
"names",
|
|
1419
1419
|
"change",
|
|
1420
|
+
"bring",
|
|
1420
1421
|
"view",
|
|
1421
1422
|
"sort",
|
|
1423
|
+
"order",
|
|
1422
1424
|
"move",
|
|
1423
1425
|
"where",
|
|
1424
1426
|
"whose",
|
|
@@ -1432,7 +1434,9 @@ const CONTEXT_CUBE_SOURCE = new InjectionToken("CONTEXT_CUBE_SOURCE");
|
|
|
1432
1434
|
const CONTEXT_CUBE_WORDS = new InjectionToken("CONTEXT_CUBE_WORDS");
|
|
1433
1435
|
const PART_ICONS = {
|
|
1434
1436
|
hide: "shown",
|
|
1435
|
-
where: "place"
|
|
1437
|
+
where: "place",
|
|
1438
|
+
bring: "move",
|
|
1439
|
+
order: "sort"
|
|
1436
1440
|
};
|
|
1437
1441
|
function partsLevel(parts, words, now = {}) {
|
|
1438
1442
|
return orderParts(parts).map((p) => ({
|
|
@@ -1505,6 +1509,36 @@ function sortItems(items, by, dir, text = "natural") {
|
|
|
1505
1509
|
return sign * compare(a.value, b.value) || a.at - b.at;
|
|
1506
1510
|
}).map((x) => x.item);
|
|
1507
1511
|
}
|
|
1512
|
+
const MINE_SORT = "mine";
|
|
1513
|
+
function moveBefore(order, piece, before, opts = {}) {
|
|
1514
|
+
const fixed = opts.fixedFirst ?? null;
|
|
1515
|
+
if (fixed !== null && (piece === fixed || before === fixed)) return {
|
|
1516
|
+
order: [...order],
|
|
1517
|
+
refused: "fixed-first"
|
|
1518
|
+
};
|
|
1519
|
+
if (!order.includes(piece) || before === piece) return {
|
|
1520
|
+
order: [...order],
|
|
1521
|
+
refused: null
|
|
1522
|
+
};
|
|
1523
|
+
const rest = order.filter((p) => p !== piece);
|
|
1524
|
+
const at = before === null ? -1 : rest.indexOf(before);
|
|
1525
|
+
rest.splice(at < 0 ? rest.length : at, 0, piece);
|
|
1526
|
+
return {
|
|
1527
|
+
order: rest,
|
|
1528
|
+
refused: null
|
|
1529
|
+
};
|
|
1530
|
+
}
|
|
1531
|
+
function orderOf(order, held, opts = {}) {
|
|
1532
|
+
const fixed = opts.fixedFirst ?? null;
|
|
1533
|
+
return order.map((key, at) => ({
|
|
1534
|
+
key,
|
|
1535
|
+
at,
|
|
1536
|
+
held: key === held,
|
|
1537
|
+
fixed: key === fixed,
|
|
1538
|
+
tap: key === held ? null : "before",
|
|
1539
|
+
refused: key !== held && key === fixed ? "fixed-first" : null
|
|
1540
|
+
}));
|
|
1541
|
+
}
|
|
1508
1542
|
function namesLevel(names, words, opts = {}) {
|
|
1509
1543
|
const tiles = [...names.filter((n) => n.current), ...names.filter((n) => !n.current).reverse()].map((n, i) => ({
|
|
1510
1544
|
key: `name:${i}:${n.name}`,
|
|
@@ -1582,6 +1616,36 @@ function sortDirectionsLevel(option, now, words) {
|
|
|
1582
1616
|
data: dir
|
|
1583
1617
|
}));
|
|
1584
1618
|
}
|
|
1619
|
+
function orderLevel(places, words) {
|
|
1620
|
+
const tiles = places.map((p) => ({
|
|
1621
|
+
key: "order:" + p.key,
|
|
1622
|
+
title: words.title(p),
|
|
1623
|
+
line: words.line?.(p) ?? null,
|
|
1624
|
+
icon: "sort",
|
|
1625
|
+
inUse: p.held,
|
|
1626
|
+
pale: p.fixed,
|
|
1627
|
+
data: p
|
|
1628
|
+
}));
|
|
1629
|
+
if (places.length && !places[places.length - 1].held) tiles.push({
|
|
1630
|
+
key: "order:last",
|
|
1631
|
+
title: words.last.title,
|
|
1632
|
+
line: words.last.line ?? null,
|
|
1633
|
+
icon: "down",
|
|
1634
|
+
data: null
|
|
1635
|
+
});
|
|
1636
|
+
return tiles;
|
|
1637
|
+
}
|
|
1638
|
+
function addLevel(ways) {
|
|
1639
|
+
const tile = (w) => ({
|
|
1640
|
+
key: "add:" + w.key,
|
|
1641
|
+
title: w.title,
|
|
1642
|
+
line: w.line ?? null,
|
|
1643
|
+
icon: w.icon ?? (w.adds ? "plus" : "move"),
|
|
1644
|
+
adds: !!w.adds,
|
|
1645
|
+
data: w
|
|
1646
|
+
});
|
|
1647
|
+
return [...ways.filter((w) => !w.adds), ...ways.filter((w) => w.adds)].map(tile);
|
|
1648
|
+
}
|
|
1585
1649
|
function insideOf(source, piece) {
|
|
1586
1650
|
const seen = /* @__PURE__ */ new Set();
|
|
1587
1651
|
const walk = [...source.partsOf(piece)];
|
|
@@ -1698,6 +1762,66 @@ function whereLevel(places, words = {}, opts = {}) {
|
|
|
1698
1762
|
data: p
|
|
1699
1763
|
}));
|
|
1700
1764
|
}
|
|
1765
|
+
function bringOf(source, into, opts = {}) {
|
|
1766
|
+
const at = opts.at ?? source.top;
|
|
1767
|
+
const hidden = (id) => !!source.hidden?.(id);
|
|
1768
|
+
const shown = (place) => source.partsOf(place).filter((p) => !hidden(p));
|
|
1769
|
+
const inInto = (p) => source.placesOf(p).includes(into);
|
|
1770
|
+
const can = (p) => p !== into && !inInto(p) && !refusalOf(source, p, into);
|
|
1771
|
+
const reached = /* @__PURE__ */ new Map();
|
|
1772
|
+
const reaches = (q, trail = /* @__PURE__ */ new Set()) => {
|
|
1773
|
+
if (reached.has(q)) return reached.get(q);
|
|
1774
|
+
if (trail.has(q)) return false;
|
|
1775
|
+
trail.add(q);
|
|
1776
|
+
const r = shown(q).some((p) => can(p) || inInto(p) || reaches(p, trail));
|
|
1777
|
+
reached.set(q, r);
|
|
1778
|
+
return r;
|
|
1779
|
+
};
|
|
1780
|
+
return (opts.pieces ? opts.pieces.filter((p) => !hidden(p)) : shown(at)).filter((p) => p !== at || !!opts.pieces).map((p) => {
|
|
1781
|
+
const places = source.placesOf(p);
|
|
1782
|
+
const others = places.filter((q) => q !== into);
|
|
1783
|
+
const deeper = !opts.pieces && shown(p).length > 0 && reaches(p);
|
|
1784
|
+
if (p === into) return {
|
|
1785
|
+
key: p,
|
|
1786
|
+
title: source.nameOf(p),
|
|
1787
|
+
in: false,
|
|
1788
|
+
given: false,
|
|
1789
|
+
into: true,
|
|
1790
|
+
holdsInto: false,
|
|
1791
|
+
tap: null,
|
|
1792
|
+
refused: "inside-itself",
|
|
1793
|
+
places: others,
|
|
1794
|
+
deeper: false
|
|
1795
|
+
};
|
|
1796
|
+
const stands = places.includes(into);
|
|
1797
|
+
const given = (source.givenPlaceOf?.(p) ?? null) === into;
|
|
1798
|
+
return {
|
|
1799
|
+
key: p,
|
|
1800
|
+
title: source.nameOf(p),
|
|
1801
|
+
in: stands,
|
|
1802
|
+
given: stands && given,
|
|
1803
|
+
into: false,
|
|
1804
|
+
holdsInto: !stands && wouldLoop(source, p, into),
|
|
1805
|
+
tap: stands ? "take-out" : "stand",
|
|
1806
|
+
refused: stands ? given ? "given-place" : places.length === 1 ? "last-place" : null : refusalOf(source, p, into),
|
|
1807
|
+
places: others,
|
|
1808
|
+
deeper
|
|
1809
|
+
};
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
function bringLevel(pieces, words = {}, opts = {}) {
|
|
1813
|
+
const pathOf = opts.pathOf ?? ((p) => ["bring", p.key]);
|
|
1814
|
+
return pieces.map((p) => ({
|
|
1815
|
+
key: "bring:" + p.key,
|
|
1816
|
+
title: words.title?.(p) ?? p.title,
|
|
1817
|
+
line: words.line?.(p) ?? null,
|
|
1818
|
+
icon: "place",
|
|
1819
|
+
inUse: p.in,
|
|
1820
|
+
pale: p.tap === null || !p.in && p.refused !== null,
|
|
1821
|
+
zoom: p.deeper ? pathOf(p) : null,
|
|
1822
|
+
data: p
|
|
1823
|
+
}));
|
|
1824
|
+
}
|
|
1701
1825
|
const TURNING_SIDES = 4;
|
|
1702
1826
|
function turningRows(pieces, own, cols = 3, rows = cols) {
|
|
1703
1827
|
const across = Math.max(1, Math.floor(cols));
|
|
@@ -2545,6 +2669,64 @@ function contextIcon(tile) {
|
|
|
2545
2669
|
if (tile.icon === "hide") return "shown";
|
|
2546
2670
|
return "face";
|
|
2547
2671
|
}
|
|
2672
|
+
var ContextAttrs = class ContextAttrs {
|
|
2673
|
+
ccAttrs = input(...ngDevMode ? [void 0, { debugName: "ccAttrs" }] : /* istanbul ignore next */ []);
|
|
2674
|
+
el = inject(ElementRef);
|
|
2675
|
+
renderer = inject(Renderer2);
|
|
2676
|
+
set = [];
|
|
2677
|
+
constructor() {
|
|
2678
|
+
effect(() => {
|
|
2679
|
+
const attrs = this.ccAttrs() ?? {};
|
|
2680
|
+
const node = this.el.nativeElement;
|
|
2681
|
+
const next = Object.keys(attrs).filter((k) => k.startsWith("data-") && attrs[k] != null);
|
|
2682
|
+
for (const k of this.set) if (!next.includes(k)) this.renderer.removeAttribute(node, k);
|
|
2683
|
+
for (const k of next) this.renderer.setAttribute(node, k, attrs[k]);
|
|
2684
|
+
this.set = next;
|
|
2685
|
+
});
|
|
2686
|
+
}
|
|
2687
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
2688
|
+
minVersion: "12.0.0",
|
|
2689
|
+
version: "22.2.4",
|
|
2690
|
+
ngImport: i0,
|
|
2691
|
+
type: ContextAttrs,
|
|
2692
|
+
deps: [],
|
|
2693
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
2694
|
+
});
|
|
2695
|
+
static ɵdir = i0.ɵɵngDeclareDirective({
|
|
2696
|
+
minVersion: "17.1.0",
|
|
2697
|
+
version: "22.2.4",
|
|
2698
|
+
type: ContextAttrs,
|
|
2699
|
+
isStandalone: true,
|
|
2700
|
+
selector: "[ccAttrs]",
|
|
2701
|
+
inputs: { ccAttrs: {
|
|
2702
|
+
classPropertyName: "ccAttrs",
|
|
2703
|
+
publicName: "ccAttrs",
|
|
2704
|
+
isSignal: true,
|
|
2705
|
+
isRequired: false,
|
|
2706
|
+
transformFunction: null
|
|
2707
|
+
} },
|
|
2708
|
+
ngImport: i0
|
|
2709
|
+
});
|
|
2710
|
+
};
|
|
2711
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
2712
|
+
minVersion: "12.0.0",
|
|
2713
|
+
version: "22.2.4",
|
|
2714
|
+
ngImport: i0,
|
|
2715
|
+
type: ContextAttrs,
|
|
2716
|
+
decorators: [{
|
|
2717
|
+
type: Directive,
|
|
2718
|
+
args: [{ selector: "[ccAttrs]" }]
|
|
2719
|
+
}],
|
|
2720
|
+
ctorParameters: () => [],
|
|
2721
|
+
propDecorators: { ccAttrs: [{
|
|
2722
|
+
type: i0.Input,
|
|
2723
|
+
args: [{
|
|
2724
|
+
isSignal: true,
|
|
2725
|
+
alias: "ccAttrs",
|
|
2726
|
+
required: false
|
|
2727
|
+
}]
|
|
2728
|
+
}] }
|
|
2729
|
+
});
|
|
2548
2730
|
var CubeContext = class CubeContext {
|
|
2549
2731
|
held = input.required(...ngDevMode ? [{ debugName: "held" }] : /* istanbul ignore next */ []);
|
|
2550
2732
|
path = input([], ...ngDevMode ? [{ debugName: "path" }] : /* istanbul ignore next */ []);
|
|
@@ -2696,7 +2878,7 @@ var CubeContext = class CubeContext {
|
|
|
2696
2878
|
[class.cc-adds]="adds()"
|
|
2697
2879
|
>
|
|
2698
2880
|
<ng-template [cubeSquareTile]="tiles()" let-t let-level="level">
|
|
2699
|
-
<div class="cc-cell">
|
|
2881
|
+
<div class="cc-cell" [ccAttrs]="t.attrs">
|
|
2700
2882
|
<button
|
|
2701
2883
|
type="button"
|
|
2702
2884
|
[class]="'cc-tile cc-l' + level"
|
|
@@ -2777,6 +2959,12 @@ var CubeContext = class CubeContext {
|
|
|
2777
2959
|
type: CubeSquareTile,
|
|
2778
2960
|
selector: "ng-template[cubeSquareTile]",
|
|
2779
2961
|
inputs: ["cubeSquareTile"]
|
|
2962
|
+
},
|
|
2963
|
+
{
|
|
2964
|
+
kind: "directive",
|
|
2965
|
+
type: ContextAttrs,
|
|
2966
|
+
selector: "[ccAttrs]",
|
|
2967
|
+
inputs: ["ccAttrs"]
|
|
2780
2968
|
}
|
|
2781
2969
|
],
|
|
2782
2970
|
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
@@ -2794,7 +2982,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
2794
2982
|
imports: [
|
|
2795
2983
|
CubeIcon,
|
|
2796
2984
|
CubeSquare,
|
|
2797
|
-
CubeSquareTile
|
|
2985
|
+
CubeSquareTile,
|
|
2986
|
+
ContextAttrs
|
|
2798
2987
|
],
|
|
2799
2988
|
template: `
|
|
2800
2989
|
<cube-square
|
|
@@ -2805,7 +2994,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
2805
2994
|
[class.cc-adds]="adds()"
|
|
2806
2995
|
>
|
|
2807
2996
|
<ng-template [cubeSquareTile]="tiles()" let-t let-level="level">
|
|
2808
|
-
<div class="cc-cell">
|
|
2997
|
+
<div class="cc-cell" [ccAttrs]="t.attrs">
|
|
2809
2998
|
<button
|
|
2810
2999
|
type="button"
|
|
2811
3000
|
[class]="'cc-tile cc-l' + level"
|
|
@@ -3207,6 +3396,6 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
3207
3396
|
}]
|
|
3208
3397
|
}
|
|
3209
3398
|
});
|
|
3210
|
-
export { CONTEXT_CUBE_SOURCE, CONTEXT_CUBE_WORDS, CONTEXT_PART_ORDER, CUBE_CARRY_CLASSES, CUBE_CARRY_MOVE, CUBE_DROP_OUT, CUBE_HOLD_MS, CUBE_HOLD_SLOP, CUBE_ICON_NAMES, CUBE_LOADING_COLOURS, CUBE_LOADING_LEVELS, CUBE_LOADING_STEP_MS, CUBE_LOADING_STICKERS, CUBE_LOADING_WAYS, CUBE_LOADING_WIDTH, CUBE_PINCH_APART, CUBE_PINCH_TOGETHER, CUBE_WHEEL_QUIET_MS, CubeCarry, CubeContext, CubeHold, CubeIcon, CubeLoading, CubePicture, CubePinch, CubeSquare, CubeSquareTile, PART_ICONS, SQUARE_LIST_ROW, SQUARE_MAX_SIDE, TEXT_ORDERS, TURNING_BELOW, TURNING_NUDGE_UNTIL, TURNING_SIDES, VIEW_KEYS, contextIcon, contextLevelFor, contextSquare, cubeIconCells, directionWords, drawCube, gridFor, hideLevel, insideOf, isView, loadingStickers, loadingWayFor, namesLevel, orderParts, partsLevel, placesOf, refusalOf, sizeFor, sortDirectionsLevel, sortItems, sortLevel, squareGap, squareLayout, squareLevelFor, startsWheelGesture, stillStep, turningFront, turningRows, viewLevel, whereLevel, wouldLoop };
|
|
3399
|
+
export { CONTEXT_CUBE_SOURCE, CONTEXT_CUBE_WORDS, CONTEXT_PART_ORDER, CUBE_CARRY_CLASSES, CUBE_CARRY_MOVE, CUBE_DROP_OUT, CUBE_HOLD_MS, CUBE_HOLD_SLOP, CUBE_ICON_NAMES, CUBE_LOADING_COLOURS, CUBE_LOADING_LEVELS, CUBE_LOADING_STEP_MS, CUBE_LOADING_STICKERS, CUBE_LOADING_WAYS, CUBE_LOADING_WIDTH, CUBE_PINCH_APART, CUBE_PINCH_TOGETHER, CUBE_WHEEL_QUIET_MS, CubeCarry, CubeContext, CubeHold, CubeIcon, CubeLoading, CubePicture, CubePinch, CubeSquare, CubeSquareTile, MINE_SORT, PART_ICONS, SQUARE_LIST_ROW, SQUARE_MAX_SIDE, TEXT_ORDERS, TURNING_BELOW, TURNING_NUDGE_UNTIL, TURNING_SIDES, VIEW_KEYS, addLevel, bringLevel, bringOf, contextIcon, contextLevelFor, contextSquare, cubeIconCells, directionWords, drawCube, gridFor, hideLevel, insideOf, isView, loadingStickers, loadingWayFor, moveBefore, namesLevel, orderLevel, orderOf, orderParts, partsLevel, placesOf, refusalOf, sizeFor, sortDirectionsLevel, sortItems, sortLevel, squareGap, squareLayout, squareLevelFor, startsWheelGesture, stillStep, turningFront, turningRows, viewLevel, whereLevel, wouldLoop };
|
|
3211
3400
|
|
|
3212
3401
|
//# sourceMappingURL=selimssevgi-cube-design-angular.mjs.map
|