@liquidcars/atlas-layout 0.1.9 → 0.1.10
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/README.md +4 -2
- package/package.json +1 -1
- package/spec/ATLAS-LAYOUT-SPEC-v1.md +9 -3
- package/src/index.js +8 -1
- package/src/spec.js +6 -3
package/README.md
CHANGED
|
@@ -134,13 +134,15 @@ relations:
|
|
|
134
134
|
from: source
|
|
135
135
|
to: rules
|
|
136
136
|
label: feeds
|
|
137
|
+
text: Sends normalized source data to the rules engine.
|
|
138
|
+
url: https://example.com/relations/source-to-rules
|
|
137
139
|
mode: bidirectional
|
|
138
140
|
- from: rules
|
|
139
141
|
to: output
|
|
140
142
|
mode: broken
|
|
141
143
|
```
|
|
142
144
|
|
|
143
|
-
`mode` es la forma recomendada y el compilador siempre la emite normalizada. Para facilitar la migración se aceptan también `visual`, `render`, `type`, `direction`, `bidirectional: true` y `broken: true`, además de los alias `two-way`, `both` e `interrupted`. La forma abreviada puede incluir el modo como cuarto valor: `[from, to, label, mode]`. Un modo desconocido conserva la relación como `directed` y añade el diagnóstico `UNKNOWN_RELATION_MODE`.
|
|
145
|
+
`label` es el título corto visible junto a la conexión, `text` permite documentar su significado y `url` enlaza documentación externa desde el panel de información. `mode` es la forma recomendada y el compilador siempre la emite normalizada. Para facilitar la migración se aceptan también `visual`, `render`, `type`, `direction`, `bidirectional: true` y `broken: true`, además de los alias `two-way`, `both` e `interrupted`. La forma abreviada puede incluir el modo como cuarto valor: `[from, to, label, mode]`. Un modo desconocido conserva la relación como `directed` y añade el diagnóstico `UNKNOWN_RELATION_MODE`.
|
|
144
146
|
|
|
145
147
|
En un documento Markdown dividido, el bloque de relaciones contiene una lista YAML:
|
|
146
148
|
|
|
@@ -194,4 +196,4 @@ El resultado mantiene `palette`, `theme`, `entities` y `relations`, con `p` y `s
|
|
|
194
196
|
|
|
195
197
|
El espacio de una celda y el tamaño de la geometría son conceptos distintos. Cuando el layout asigna una celda rectangular a una geometría sin `size` explícito, la figura se centra y se escala uniformemente para caber en el menor volumen compatible; no se estira por separado en `x`, `y` y `z`. Por eso una esfera conserva `s[0] === s[1] === s[2]`, aunque su celda sea rectangular. Un `size` explícito sigue teniendo prioridad y permite al autor solicitar una proporción concreta.
|
|
196
198
|
|
|
197
|
-
`row`, `grid`/`masonry` y `volume` producen posiciones deterministas. Las constraints de tamaño y alineación, el empaquetado compacto, los grupos virtuales y la distribución `justify` forman parte del contrato estable de autoría. El algoritmo `graph` sigue reservado: por ahora emite `GRAPH_LAYOUT_FALLBACK` y usa `grid`. La proyección y el enrutado avanzado de relaciones entre contenedores permanecen como líneas de desarrollo posteriores.
|
|
199
|
+
`row`, `grid`/`masonry` y `volume` producen posiciones deterministas. `variant: masonry` desplaza las filas alternas media celda sin exigir una sección `stagger`; `stagger.offset` queda disponible como override explícito. Para conservar legibilidad frontal se recomienda `plane: xy`, y para una composición lateral, `plane: yz`. Las constraints de tamaño y alineación, el empaquetado compacto, los grupos virtuales y la distribución `justify` forman parte del contrato estable de autoría. El algoritmo `graph` sigue reservado: por ahora emite `GRAPH_LAYOUT_FALLBACK` y usa `grid`. La proyección y el enrutado avanzado de relaciones entre contenedores permanecen como líneas de desarrollo posteriores.
|
package/package.json
CHANGED
|
@@ -47,7 +47,7 @@ subject to sizeMode and diagnostics.
|
|
|
47
47
|
|
|
48
48
|
Required: id.
|
|
49
49
|
|
|
50
|
-
Common fields: name, sub, text, type, parent, children, geometry, geometryOptions,
|
|
50
|
+
Common fields: name, sub, text, url, type, parent, children, geometry, geometryOptions,
|
|
51
51
|
geometryPalette, style, layout, weight, span, size, sizeMode, p, s, c and radius.
|
|
52
52
|
|
|
53
53
|
An entity with children is a container and must explicitly declare `type: container`.
|
|
@@ -73,7 +73,10 @@ fit permits assisted layout to use the geometry's canonical size.
|
|
|
73
73
|
|
|
74
74
|
layout.algorithm accepts row, grid, volume or graph. direction accepts x, y or z.
|
|
75
75
|
Grid layouts also accept variant uniform or masonry, optional columns and rows, and
|
|
76
|
-
a plane of xz (the default), xy or yz.
|
|
76
|
+
a plane of xz (the default), xy or yz. Masonry offsets alternate rows by half a cell
|
|
77
|
+
unless `stagger.offset` explicitly overrides that distance. Use plane xy for layouts
|
|
78
|
+
intended to remain legible from the natural frontal camera, or yz for a lateral view.
|
|
79
|
+
Volume layouts additionally accept layers.
|
|
77
80
|
gap and padding are absolute numbers. justify accepts start, center, end,
|
|
78
81
|
space-between, space-around or space-evenly. These modes become distinct when a
|
|
79
82
|
row receives an explicit or constrained size. Distributed modes treat gap as the
|
|
@@ -145,7 +148,10 @@ constraints:
|
|
|
145
148
|
|
|
146
149
|
Relations require from and to entity ids. mode is directed, bidirectional or broken.
|
|
147
150
|
The aliases visual, render, type and direction are accepted for compatibility.
|
|
148
|
-
Optional fields include id, label, fromAnchor, toAnchor, priority and layout.
|
|
151
|
+
Optional fields include id, label, text, url, fromAnchor, toAnchor, priority and layout.
|
|
152
|
+
`label` is the compact caption associated with the connection; `text` is its longer
|
|
153
|
+
description and `url` links to external documentation when the relation is selected
|
|
154
|
+
in the information panel.
|
|
149
155
|
|
|
150
156
|
## Rendering
|
|
151
157
|
|
package/src/index.js
CHANGED
|
@@ -242,6 +242,8 @@ function normalizeRelations(input, validIds, diagnostics) {
|
|
|
242
242
|
index
|
|
243
243
|
};
|
|
244
244
|
if (relation.id != null) normalized.id = String(relation.id);
|
|
245
|
+
if (relation.text != null) normalized.text = String(relation.text);
|
|
246
|
+
if (relation.url != null) normalized.url = String(relation.url);
|
|
245
247
|
if (relation.fromAnchor != null || relation.from_anchor != null) normalized.fromAnchor = String(relation.fromAnchor ?? relation.from_anchor);
|
|
246
248
|
if (relation.toAnchor != null || relation.to_anchor != null) normalized.toAnchor = String(relation.toAnchor ?? relation.to_anchor);
|
|
247
249
|
return [normalized];
|
|
@@ -890,7 +892,12 @@ function packedGridLayout(items, spec, diagnostics, dimension = 2) {
|
|
|
890
892
|
for (const item of placements) {
|
|
891
893
|
const columnSize = item.span[0] * columnCell + (item.span[0] - 1) * gap;
|
|
892
894
|
const rowSize = item.span[1] * rowCell + (item.span[1] - 1) * gap;
|
|
893
|
-
const
|
|
895
|
+
const staggerOffset = spec.stagger?.offset;
|
|
896
|
+
const offset = spec.variant === "masonry" && item.cell[1] % 2 === 1
|
|
897
|
+
? (staggerOffset == null || staggerOffset === "half-cell"
|
|
898
|
+
? (columnCell + gap) / 2
|
|
899
|
+
: scalar(staggerOffset, 0))
|
|
900
|
+
: 0;
|
|
894
901
|
const slotSize = [0, 0, 0];
|
|
895
902
|
slotSize[columnAxis] = columnSize;
|
|
896
903
|
slotSize[rowAxis] = rowSize;
|
package/src/spec.js
CHANGED
|
@@ -30,6 +30,7 @@ export const ATLAS_LAYOUT_SPEC_V1 = freeze({
|
|
|
30
30
|
name: field("Visible title.", null, { type: "string" }),
|
|
31
31
|
sub: field("Visible subtitle.", null, { type: "string" }),
|
|
32
32
|
text: field("Description shown by the inspector.", null, { type: "string" }),
|
|
33
|
+
url: field("External documentation opened from the inspector.", null, { type: "url" }),
|
|
33
34
|
type: field("Structural role. Use container when declaring children; omit it for a leaf item.", ["container"]),
|
|
34
35
|
parent: field("Parent entity id.", null, { type: "string", authoring: "absolute" }),
|
|
35
36
|
children: field("Nested entities.", null, { context: "entity", sequence: true }),
|
|
@@ -56,6 +57,8 @@ export const ATLAS_LAYOUT_SPEC_V1 = freeze({
|
|
|
56
57
|
from: field("Source entity id.", null, { type: "string", required: true }),
|
|
57
58
|
to: field("Target entity id.", null, { type: "string", required: true }),
|
|
58
59
|
label: field("Text shown on the relation.", null, { type: "string" }),
|
|
60
|
+
text: field("Description shown by the inspector.", null, { type: "string" }),
|
|
61
|
+
url: field("External documentation opened from the inspector.", null, { type: "url" }),
|
|
59
62
|
mode: field("Canonical visual relation mode.", ["directed", "bidirectional", "broken"]),
|
|
60
63
|
visual: field("Historical alias for relation mode.", ["directed", "bidirectional", "broken"]),
|
|
61
64
|
fromAnchor: field("Named source anchor.", null, { type: "string" }),
|
|
@@ -69,7 +72,7 @@ export const ATLAS_LAYOUT_SPEC_V1 = freeze({
|
|
|
69
72
|
properties: freeze({
|
|
70
73
|
algorithm: field("Spatial strategy.", ["row", "grid", "volume", "graph"]),
|
|
71
74
|
direction: field("Primary semantic axis.", ["x", "y", "z"]),
|
|
72
|
-
variant: field("Regular or staggered
|
|
75
|
+
variant: field("Regular cells or masonry rows staggered by half a cell by default.", ["uniform", "masonry"]),
|
|
73
76
|
plane: field("Axes used by a two-dimensional grid.", ["xz", "xy", "yz"]),
|
|
74
77
|
packing: field("Preserve initial slots or compact free space after constraints.", ["preserve", "compact"]),
|
|
75
78
|
groups: field("Invisible sibling groups used only during layout.", null, { context: "layoutGroup", sequence: true }),
|
|
@@ -79,7 +82,7 @@ export const ATLAS_LAYOUT_SPEC_V1 = freeze({
|
|
|
79
82
|
gap: field("Spacing between children.", null, { type: "number" }),
|
|
80
83
|
padding: field("Spacing to the container boundary.", null, { type: "number" }),
|
|
81
84
|
justify: field("Row alignment or distribution within an assigned size.", ["start", "center", "end", "space-between", "space-around", "space-evenly"]),
|
|
82
|
-
stagger: field("Optional masonry offset.", null, { context: "stagger" }),
|
|
85
|
+
stagger: field("Optional override for the masonry row offset.", null, { context: "stagger" }),
|
|
83
86
|
constraints: field("Equal-size and edge-alignment rules for this layout's siblings.", null, { context: "constraint", sequence: true })
|
|
84
87
|
})
|
|
85
88
|
}),
|
|
@@ -169,7 +172,7 @@ export const ATLAS_LAYOUT_SPEC_V1 = freeze({
|
|
|
169
172
|
stagger: freeze({
|
|
170
173
|
label: "Stagger",
|
|
171
174
|
properties: freeze({
|
|
172
|
-
offset: field("Masonry row offset.", ["half-cell"], { type: "string" })
|
|
175
|
+
offset: field("Masonry row offset; defaults to half-cell.", ["half-cell"], { type: "string" })
|
|
173
176
|
})
|
|
174
177
|
}),
|
|
175
178
|
label: freeze({ label: "Label appearance", properties: freeze({ color: field("Label colour.", null, { valueSource: "palette" }), opacity: field("Label opacity.", null, { type: "number" }) }) }),
|