@harmonics/lattice-ui 0.4.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 +21 -0
- package/README.md +40 -5
- package/dist/define.js +1 -1
- package/dist/{elements-BJBhL4LI.js → elements-Czlt91Ar.js} +9 -1
- package/dist/index.js +1 -1
- package/dist/types/elements/sky.d.ts +3 -0
- package/package.json +1 -1
- package/react.d.ts +9 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,27 @@
|
|
|
3
3
|
`@harmonics/lattice-ui` follows semantic versioning; while it is `0.x`, a minor version may change
|
|
4
4
|
an element's inputs, events or tokens, and says so here.
|
|
5
5
|
|
|
6
|
+
## 0.5.0
|
|
7
|
+
|
|
8
|
+
- `<shears-pad>` always ends a stroke. `strokeend` carries `cancelled`: true when the stroke was cut
|
|
9
|
+
short (the pointer cancelled or its capture lost, `disabled` set mid-stroke, the pad taken off
|
|
10
|
+
the page), where before no `strokeend` came at all. `pointercancel` is now `cancelled: true`.
|
|
11
|
+
`stroke` carries `point`, the newest point.
|
|
12
|
+
- **Types:** `stroke` and `strokeend` are typed on `ShearsPadElement` (`ShearsPadEventMap`, and
|
|
13
|
+
`StrokeEndDetail`) instead of on every element's `HTMLElementEventMap`. A listener added on a
|
|
14
|
+
plain `HTMLElement` reference now needs the pad's type, or a cast.
|
|
15
|
+
- `<lattice-face>` idles on animation frames and stops while off screen or in a hidden tab; it
|
|
16
|
+
follows `prefers-reduced-motion` as it changes, not only as it was when first drawn.
|
|
17
|
+
- An element moved on the page keeps its drawing and state; it lets go only once it stays off.
|
|
18
|
+
- `defineX(name)` registers an element under a tag of your own. A tag another element holds is
|
|
19
|
+
left to it with a console warning instead of in silence.
|
|
20
|
+
- `<lattice-shape>` warns once when `parts` is a string that is not JSON (the usual cause: React
|
|
21
|
+
set it before the elements were defined). `parts` read twice is the same array.
|
|
22
|
+
- `@harmonics/lattice-ui/hexes` exports `crossesCell`, `crossesLine` and `crossesRing`.
|
|
23
|
+
- `<hex-sky orient="flat">`: the lattice turned a quarter turn clockwise about its origin, for pages
|
|
24
|
+
whose pieces have flat-topped cells. `x`, `y` and `scale` mean what they did; the default,
|
|
25
|
+
`pointy`, draws exactly what 0.4.0 did.
|
|
26
|
+
|
|
6
27
|
## 0.4.0
|
|
7
28
|
|
|
8
29
|
- The magnet in `@harmonics/lattice-ui/hexes`: `magnetOf(piece, dx, dy, held)` says where to draw a
|
package/README.md
CHANGED
|
@@ -25,7 +25,15 @@ npm install @harmonics/lattice-ui
|
|
|
25
25
|
|
|
26
26
|
`@harmonics/lattice-ui` itself defines nothing when imported: call `defineLatticeElements()` (or
|
|
27
27
|
one element's `defineLatticeFace()`, …) in a browser. Both are safe to import in a server render;
|
|
28
|
-
there they do nothing. Every input is both an attribute and a property
|
|
28
|
+
there they do nothing. Every input is both an attribute and a property; a property set does not
|
|
29
|
+
change the attribute, so style by class rather than by `[mood=…]`. A value an input does not know
|
|
30
|
+
falls back to its default.
|
|
31
|
+
|
|
32
|
+
A tag another library already holds is left to it, with a warning. Give the element a tag of your
|
|
33
|
+
own instead: `defineHexSky("my-sky")`, and the same for every `defineX`.
|
|
34
|
+
|
|
35
|
+
An element moved on the page (a list reordered) keeps what it was doing; one taken off the page
|
|
36
|
+
lets go a moment later.
|
|
29
37
|
|
|
30
38
|
## Elements
|
|
31
39
|
|
|
@@ -33,7 +41,8 @@ there they do nothing. Every input is both an attribute and a property.
|
|
|
33
41
|
|
|
34
42
|
A pale hexagon plate raised off the page with a face on it, in 1,536 of the lattice's triangles.
|
|
35
43
|
It idles (blinks, bobs), laughs with relief when `pulse` goes up, and sinks the old face as a new
|
|
36
|
-
one comes. Under `prefers-reduced-motion
|
|
44
|
+
one comes. Under `prefers-reduced-motion` (followed as it changes), or `still`, it holds still and
|
|
45
|
+
only changes. Off screen, or in a hidden tab, it does not idle.
|
|
37
46
|
|
|
38
47
|
| Input | Type | Default | |
|
|
39
48
|
|---|---|---|---|
|
|
@@ -83,6 +92,7 @@ Decorative.
|
|
|
83
92
|
| Input | Type | Default | |
|
|
84
93
|
|---|---|---|---|
|
|
85
94
|
| `kind` | `sky` `earth` | `sky` | Earth: cells broken into triangles, on the earth's colour |
|
|
95
|
+
| `orient` | `pointy` `flat` | `pointy` | Flat: the lattice turned a quarter turn clockwise about its origin, so its cells have flat tops and bottoms |
|
|
86
96
|
| `scale` | number | `1` | The lattice's size |
|
|
87
97
|
| `x`, `y` | number (pixels) | `0` | Where the lattice's origin sits from the element's top-left, so a sky showing part of a larger one keeps its cells in place |
|
|
88
98
|
|
|
@@ -93,16 +103,20 @@ cuts is yours to decide. Put it over what can be cut and size it as any block.
|
|
|
93
103
|
|
|
94
104
|
| Event | `detail` | |
|
|
95
105
|
|---|---|---|
|
|
96
|
-
| `stroke` | `{ points, fresh }` | At every move; `fresh` on a stroke's first
|
|
97
|
-
| `strokeend` | `{ points }` |
|
|
106
|
+
| `stroke` | `{ points, point, fresh }` | At every move; `point` is the newest, `fresh` on a stroke's first |
|
|
107
|
+
| `strokeend` | `{ points, cancelled }` | Once per stroke: lifted, or `cancelled` when cut short (the pointer cancelled or lost, `disabled` set, the pad taken off the page) |
|
|
98
108
|
|
|
99
109
|
Points are in the element's own pixels from its top-left. `disabled` stops it taking strokes. A
|
|
100
110
|
cut by pointer has no keyboard of its own: give the same action a button.
|
|
101
111
|
|
|
102
112
|
```js
|
|
103
113
|
pad.addEventListener("stroke", (e) => cutAlong(e.detail.points));
|
|
114
|
+
pad.addEventListener("strokeend", (e) => (e.detail.cancelled ? undo() : commit()));
|
|
104
115
|
```
|
|
105
116
|
|
|
117
|
+
`ShearsPadEventMap` types these on the pad's own `addEventListener`. To find what a stroke cut,
|
|
118
|
+
see [Cutting](#cutting).
|
|
119
|
+
|
|
106
120
|
### `<lattice-icon>`
|
|
107
121
|
|
|
108
122
|
`name="shears"` or `name="done"`, in the text's colour, a step square
|
|
@@ -145,7 +159,9 @@ them: `lattice-icon::part(done-cell)`, `::part(done-check)`, `::part(shears-blad
|
|
|
145
159
|
|
|
146
160
|
- **React 19**: use the tags directly; add `import type {} from "@harmonics/lattice-ui/react"`
|
|
147
161
|
for their props. React 19 sets inputs as properties, so `parts={[…]}` works, and listens with
|
|
148
|
-
`onstroke` / `onstrokeend`.
|
|
162
|
+
`onstroke` / `onstrokeend`. Define the elements before React first renders them: until then
|
|
163
|
+
React cannot see the property and sets `parts` as the attribute `"[object Object]"`, which draws
|
|
164
|
+
nothing (the shape warns once in the console when that happens).
|
|
149
165
|
- **Solid**: `import type {} from "@harmonics/lattice-ui/solid"`; set objects with `prop:parts`;
|
|
150
166
|
listen with `on:stroke`.
|
|
151
167
|
- **Vue**: tell the compiler the tags are custom elements
|
|
@@ -229,6 +245,25 @@ onPointerUp((dx, dy) => {
|
|
|
229
245
|
|
|
230
246
|
Under reduced motion, draw the piece in its slot and leave out the animation.
|
|
231
247
|
|
|
248
|
+
### Cutting
|
|
249
|
+
|
|
250
|
+
What a `<shears-pad>` stroke went through. A stroke goes through an outline when it goes in at one
|
|
251
|
+
side and out at another; one that only grazes a corner, or stops inside, does not.
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
import { crossesCell, crossesLine, crossesRing } from "@harmonics/lattice-ui/hexes";
|
|
255
|
+
|
|
256
|
+
pad.addEventListener("stroke", (e) => {
|
|
257
|
+
const stroke = e.detail.points; // in the sky's pixels when the pad covers the sky at scale 1
|
|
258
|
+
const isCut = (part) => part.kind === "cell" && crossesCell(stroke, part.at);
|
|
259
|
+
const cut = pieces.filter((p) => p.parts.some(isCut));
|
|
260
|
+
const severed = crossesLine(stroke, branch); // through a line of points
|
|
261
|
+
const through = crossesRing(stroke, outline); // through any closed outline
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
`crossesCell(stroke, hex, lift)` takes the cell as drawn `lift` above its place.
|
|
266
|
+
|
|
232
267
|
## Server rendering
|
|
233
268
|
|
|
234
269
|
Importing either entry on a server does nothing and throws nothing. Render the tags as markup;
|
package/dist/define.js
CHANGED
|
@@ -1709,12 +1709,14 @@ var Cn = /*#__PURE__*/ P("<svg class=trail part=trail aria-hidden=true><polyline
|
|
|
1709
1709
|
}, Dn = () => kt(wn, En), On = ":host{background:var(--color-tree-sky);display:block;position:relative}:host([kind=earth]){background:var(--color-tree-earth)}.sky{width:100%;height:100%;position:absolute;inset:0;overflow:hidden}.line{fill:none;stroke:var(--color-tree-lattice-sky);stroke-width:var(--tree-rule-width)}:host([kind=earth]) .line{stroke:var(--color-tree-lattice-earth)}", kn = /*#__PURE__*/ P("<svg class=sky part=sky aria-hidden=true><defs><pattern patternUnits=userSpaceOnUse><path class=line></path></pattern></defs><rect width=100% height=100%>"), An = "hex-sky", jn = Ot(On), Mn = 0, Nn = class t extends jt {
|
|
1710
1710
|
static observedAttributes = [
|
|
1711
1711
|
"kind",
|
|
1712
|
+
"orient",
|
|
1712
1713
|
"scale",
|
|
1713
1714
|
"x",
|
|
1714
1715
|
"y"
|
|
1715
1716
|
];
|
|
1716
1717
|
inputs = t.observedAttributes;
|
|
1717
1718
|
kindSignal = T("sky");
|
|
1719
|
+
orientSignal = T("pointy");
|
|
1718
1720
|
scaleSignal = T(1);
|
|
1719
1721
|
xSignal = T(0);
|
|
1720
1722
|
ySignal = T(0);
|
|
@@ -1724,6 +1726,12 @@ var Cn = /*#__PURE__*/ P("<svg class=trail part=trail aria-hidden=true><polyline
|
|
|
1724
1726
|
set kind(e) {
|
|
1725
1727
|
this.kindSignal[1](String(e ?? "").toLowerCase() === "earth" ? "earth" : "sky");
|
|
1726
1728
|
}
|
|
1729
|
+
get orient() {
|
|
1730
|
+
return this.orientSignal[0]();
|
|
1731
|
+
}
|
|
1732
|
+
set orient(e) {
|
|
1733
|
+
this.orientSignal[1](String(e ?? "").toLowerCase() === "flat" ? "flat" : "pointy");
|
|
1734
|
+
}
|
|
1727
1735
|
get scale() {
|
|
1728
1736
|
return this.scaleSignal[0]();
|
|
1729
1737
|
}
|
|
@@ -1754,7 +1762,7 @@ var Cn = /*#__PURE__*/ P("<svg class=trail part=trail aria-hidden=true><polyline
|
|
|
1754
1762
|
return (() => {
|
|
1755
1763
|
var r = kn(), a = r.firstChild, o = a.firstChild, s = o.firstChild, c = a.nextSibling;
|
|
1756
1764
|
return F(o, "id", t), F(c, "fill", `url(#${t})`), E((t) => {
|
|
1757
|
-
var r = e.width, a = e.height, c = `translate(${n.x} ${n.y}) scale(${n.scale})`, l = i[n.kind];
|
|
1765
|
+
var r = e.width, a = e.height, c = `translate(${n.x} ${n.y})${n.orient === "flat" ? " rotate(90)" : ""} scale(${n.scale})`, l = i[n.kind];
|
|
1758
1766
|
return r !== t.e && F(o, "width", t.e = r), a !== t.t && F(o, "height", t.t = a), c !== t.a && F(o, "patternTransform", t.a = c), l !== t.o && F(s, "d", t.o = l), t;
|
|
1759
1767
|
}, {
|
|
1760
1768
|
e: void 0,
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { x as FACES, _ as FACE_TAG, n as HexSky, p as ICON_NAMES, m as ICON_TAG, v as LatticeFace, h as LatticeIcon, c as LatticeShape, y as MOODS, d as SHAPE_NAMES, l as SHAPE_TAG, a as SHEARS_TAG, r as SKY_TAG, o as ShearsPadElement, f as TONES, i as defineHexSky, t as defineLatticeElements, b as defineLatticeFace, g as defineLatticeIcon, u as defineLatticeShape, s as defineShearsPad } from "./elements-
|
|
1
|
+
export { x as FACES, _ as FACE_TAG, n as HexSky, p as ICON_NAMES, m as ICON_TAG, v as LatticeFace, h as LatticeIcon, c as LatticeShape, y as MOODS, d as SHAPE_NAMES, l as SHAPE_TAG, a as SHEARS_TAG, r as SKY_TAG, o as ShearsPadElement, f as TONES, i as defineHexSky, t as defineLatticeElements, b as defineLatticeFace, g as defineLatticeIcon, u as defineLatticeShape, s as defineShearsPad } from "./elements-Czlt91Ar.js";
|
|
@@ -3,11 +3,14 @@ export declare const SKY_TAG = "hex-sky";
|
|
|
3
3
|
export declare class HexSky extends LatticeElement {
|
|
4
4
|
static readonly observedAttributes: string[];
|
|
5
5
|
private readonly kindSignal;
|
|
6
|
+
private readonly orientSignal;
|
|
6
7
|
private readonly scaleSignal;
|
|
7
8
|
private readonly xSignal;
|
|
8
9
|
private readonly ySignal;
|
|
9
10
|
get kind(): "sky" | "earth";
|
|
10
11
|
set kind(kind: string);
|
|
12
|
+
get orient(): "pointy" | "flat";
|
|
13
|
+
set orient(orient: string);
|
|
11
14
|
get scale(): number;
|
|
12
15
|
set scale(scale: number | string);
|
|
13
16
|
get x(): number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harmonics/lattice-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "The Harmonics tree's look as Custom Elements: a lattice face, the hexagon sky, raised lattice shapes, a shears cut gesture and two marks. Any page, any framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/react.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type {
|
|
|
11
11
|
ShapeName,
|
|
12
12
|
ShearsPadElement,
|
|
13
13
|
StrokeDetail,
|
|
14
|
-
|
|
14
|
+
StrokeEndDetail,
|
|
15
15
|
} from "./dist/types/elements/index";
|
|
16
16
|
|
|
17
17
|
type Base<E> = DetailedHTMLProps<HTMLAttributes<E>, E>;
|
|
@@ -28,7 +28,13 @@ declare module "react" {
|
|
|
28
28
|
label?: string;
|
|
29
29
|
decorative?: boolean;
|
|
30
30
|
};
|
|
31
|
-
"hex-sky": Base<HexSky> & {
|
|
31
|
+
"hex-sky": Base<HexSky> & {
|
|
32
|
+
kind?: "sky" | "earth";
|
|
33
|
+
orient?: "pointy" | "flat";
|
|
34
|
+
scale?: number;
|
|
35
|
+
x?: number;
|
|
36
|
+
y?: number;
|
|
37
|
+
};
|
|
32
38
|
"lattice-shape": Base<LatticeShape> & {
|
|
33
39
|
shape?: ShapeName;
|
|
34
40
|
parts?: Part[] | string;
|
|
@@ -40,7 +46,7 @@ declare module "react" {
|
|
|
40
46
|
"shears-pad": Base<ShearsPadElement> & {
|
|
41
47
|
disabled?: boolean;
|
|
42
48
|
onstroke?: (event: CustomEvent<StrokeDetail>) => void;
|
|
43
|
-
onstrokeend?: (event: CustomEvent<
|
|
49
|
+
onstrokeend?: (event: CustomEvent<StrokeEndDetail>) => void;
|
|
44
50
|
};
|
|
45
51
|
"lattice-icon": Base<LatticeIcon> & { name?: IconName; label?: string };
|
|
46
52
|
}
|