astroidjs 0.4.1 → 0.6.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.
|
@@ -43,7 +43,7 @@ export declare const SECTION_SETTINGS: Record<string, SectionField>;
|
|
|
43
43
|
* array — `"2"` for a top-level section, `"2.blocks.0"` for a block inside it —
|
|
44
44
|
* and every marker the component stamps is built from it. Passing it down (rather
|
|
45
45
|
* than having each component work out its own depth) is what lets the exact same
|
|
46
|
-
* component render as a section or as a block, and what keeps `data-louise-
|
|
46
|
+
* component render as a section or as a block, and what keeps `data-louise-node`
|
|
47
47
|
* paths correct at any nesting depth.
|
|
48
48
|
*/
|
|
49
49
|
export interface SectionRenderProps {
|
package/dist/map/scaffold.js
CHANGED
|
@@ -194,7 +194,13 @@ export function generateMapEmbedComponent(config) {
|
|
|
194
194
|
" for (const entry of entries) {",
|
|
195
195
|
" if (!entry.isIntersecting) continue;",
|
|
196
196
|
" obs.unobserve(entry.target);",
|
|
197
|
-
" init
|
|
197
|
+
" // `init` is async and nothing awaits it, so without this catch a",
|
|
198
|
+
" // failed chunk fetch — a page load racing a deploy is enough — is a",
|
|
199
|
+
" // silent unhandled rejection: the container just stays an empty",
|
|
200
|
+
" // tinted box with nothing in the console to explain it.",
|
|
201
|
+
" init(entry.target as HTMLElement).catch((err) => {",
|
|
202
|
+
' console.error("[astroid:map] map failed to load", err);',
|
|
203
|
+
" });",
|
|
198
204
|
" }",
|
|
199
205
|
" },",
|
|
200
206
|
' { rootMargin: "200px" },',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astroidjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Astroid — an opinionated meta-framework over Louise Toolkit and Astro for building editable, multi-editor sites on Cloudflare Workers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"access": "public"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"louise-toolkit": "0.
|
|
63
|
+
"louise-toolkit": "0.22.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@types/node": "^24.13.3",
|
|
@@ -12,10 +12,16 @@
|
|
|
12
12
|
// `data-louise-field="<collection>:<key>:<field>"` (saved as a
|
|
13
13
|
// versioned draft when the page is mounted with `versionedPageId`).
|
|
14
14
|
// • SECTION field — pass `base` (this item's path, e.g. `"2"` or `"2.blocks.0"`)
|
|
15
|
-
// plus `field`; emits `data-louise-
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
15
|
+
// plus `field`; emits `data-louise-node="<base>.<field>"` for
|
|
16
|
+
// the on-canvas section editor. `sfield` stays as the escape
|
|
17
|
+
// hatch for a path you build yourself — an array entry:
|
|
18
|
+
// sfield={`${base}.items.${i}.title`}.
|
|
19
|
+
//
|
|
20
|
+
// Since ADR 0010 A2 this is the SAME attribute the section
|
|
21
|
+
// boundary carries, one path deeper. The catalog says whether a
|
|
22
|
+
// field is edited in place and with which editor, so `type` and
|
|
23
|
+
// `multiline` no longer affect a section field's markup — they
|
|
24
|
+
// are accepted for compatibility and ignored.
|
|
19
25
|
//
|
|
20
26
|
// The `base` form is what ADR 0005 §2 asks for: "a site author writes `<Editable
|
|
21
27
|
// field="heading">` and never hand-stamps the deeper path". `<Section>` supplies
|
|
@@ -76,20 +82,26 @@ const editing = edit ?? (Astro.locals as { editMode?: boolean }).editMode ?? fal
|
|
|
76
82
|
// spreading that into `Record<string, string>` is a type error.
|
|
77
83
|
const richText: Record<string, string> =
|
|
78
84
|
type === "richtext" ? { "data-louise-type": "richtext" } : {};
|
|
79
|
-
const multilineMarker: Record<string, string> = multiline ? { "data-louise-multiline": "" } : {};
|
|
80
85
|
|
|
81
86
|
let markers: Record<string, string> = {};
|
|
82
87
|
if (editing) {
|
|
83
88
|
if (sectionPath) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
// ONE marker (ADR 0010 A2). This used to emit `data-louise-sfield` plus
|
|
90
|
+
// `data-louise-type="richtext"` plus `data-louise-multiline` — three
|
|
91
|
+
// attributes describing a field the catalog already fully describes. The
|
|
92
|
+
// editor now reads the field's type to know whether it's rich text and
|
|
93
|
+
// whether it holds more than one line, so `type` and `multiline` are inert
|
|
94
|
+
// here and kept only so an existing call site doesn't fail to compile.
|
|
95
|
+
markers = { "data-louise-node": sectionPath };
|
|
89
96
|
} else if (collection && key !== undefined && field) {
|
|
97
|
+
// The PAGE-field contract is untouched: a collection row's field is not a
|
|
98
|
+
// node in a sections tree, so it keeps its own marker and its own type hint.
|
|
90
99
|
markers = { "data-louise-field": `${collection}:${key}:${field}`, ...richText };
|
|
91
100
|
}
|
|
92
101
|
}
|
|
102
|
+
// Referenced so the deprecated prop doesn't read as unused while it's still
|
|
103
|
+
// accepted; it no longer affects the markup.
|
|
104
|
+
void multiline;
|
|
93
105
|
---
|
|
94
106
|
|
|
95
107
|
<Tag {...rest} {...markers}><slot /></Tag>
|
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
// the page's `sections` column, not props a template hand-wrote, so what renders
|
|
9
9
|
// is exactly what the on-canvas editor edits in place.
|
|
10
10
|
//
|
|
11
|
-
// Two marker responsibilities
|
|
12
|
-
// • the BOUNDARY (`data-louise-
|
|
11
|
+
// Two marker responsibilities:
|
|
12
|
+
// • the BOUNDARY (`data-louise-node="<path>"`, ADR 0010) is stamped here,
|
|
13
13
|
// because only the dispatcher knows an item's position;
|
|
14
|
-
// • the FIELDS
|
|
15
|
-
//
|
|
16
|
-
//
|
|
14
|
+
// • the FIELDS are stamped by `<Editable base={base} field="…">` inside each
|
|
15
|
+
// component, because only the component knows which of its text nodes are
|
|
16
|
+
// editable. Since A2 those carry the SAME `data-louise-node` attribute, one
|
|
17
|
+
// path deeper — the catalog says whether a field is edited in place, so the
|
|
18
|
+
// marker no longer has to.
|
|
17
19
|
//
|
|
18
20
|
// Blocks recurse through this same component with a deeper `base`. That's the
|
|
19
21
|
// whole trick: a component never learns its own depth, so a type that renders as
|
|
@@ -79,15 +81,16 @@ const type = String(item._type);
|
|
|
79
81
|
// (`<i>.blocks.<j>`), which is what the client's depth-agnostic path parser walks.
|
|
80
82
|
const blocks = Array.isArray(item.blocks) ? item.blocks : [];
|
|
81
83
|
|
|
82
|
-
// The boundary marker the on-canvas chrome draws its ring on.
|
|
83
|
-
//
|
|
84
|
-
//
|
|
84
|
+
// The boundary marker the on-canvas chrome draws its ring on. It is the item's
|
|
85
|
+
// path, verbatim — pre-0010 this line string-sniffed `base` for ".blocks." to pick
|
|
86
|
+
// between two attribute names, which was the three-attribute editing model leaking
|
|
87
|
+
// into an otherwise uniform recursive render (ADR 0010, Context). The editor
|
|
88
|
+
// resolves what a path CAN do from the catalog; the render just says where it is.
|
|
89
|
+
//
|
|
90
|
+
// `class="contents"` keeps this wrapper out of layout entirely — the ring is drawn
|
|
91
|
+
// as a box-shadow on the element itself, so an extra block box here would offset
|
|
85
92
|
// every section's spacing for the sake of an attribute.
|
|
86
|
-
const boundary = editing
|
|
87
|
-
? base.includes(".blocks.")
|
|
88
|
-
? { "data-louise-block": base }
|
|
89
|
-
: { "data-louise-section": base }
|
|
90
|
-
: {};
|
|
93
|
+
const boundary = editing ? { "data-louise-node": base } : {};
|
|
91
94
|
|
|
92
95
|
const shared = { item, base, edit: editing, mediaMeta };
|
|
93
96
|
|
|
@@ -53,7 +53,7 @@ const mediaMeta =
|
|
|
53
53
|
|
|
54
54
|
{/*
|
|
55
55
|
The host element. `mountSections(el, opts)` takes the element to scan for
|
|
56
|
-
`[data-louise-
|
|
56
|
+
`[data-louise-node]` markers and to hang on-canvas chrome off, so rendering
|
|
57
57
|
it here — rather than asking every page to remember a wrapper — is what makes
|
|
58
58
|
`<Sections>` self-sufficient: drop it on a page and the editor can find it.
|
|
59
59
|
A plain block wrapper, not `display: contents`, because the chrome positions
|
|
@@ -116,7 +116,7 @@ export const SECTION_SETTINGS: Record<string, SectionField> = {
|
|
|
116
116
|
* array — `"2"` for a top-level section, `"2.blocks.0"` for a block inside it —
|
|
117
117
|
* and every marker the component stamps is built from it. Passing it down (rather
|
|
118
118
|
* than having each component work out its own depth) is what lets the exact same
|
|
119
|
-
* component render as a section or as a block, and what keeps `data-louise-
|
|
119
|
+
* component render as a section or as a block, and what keeps `data-louise-node`
|
|
120
120
|
* paths correct at any nesting depth.
|
|
121
121
|
*/
|
|
122
122
|
export interface SectionRenderProps {
|