@loadbare/app 0.9.0 → 0.11.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/README.md +3 -3
- package/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +107 -90
- package/dist/build/assemble.js.map +1 -1
- package/dist/build/expand.d.ts +6 -1
- package/dist/build/expand.d.ts.map +1 -1
- package/dist/build/expand.js +112 -26
- package/dist/build/expand.js.map +1 -1
- package/dist/build/locations.d.ts +2 -3
- package/dist/build/locations.d.ts.map +1 -1
- package/dist/build/locations.js +2 -3
- package/dist/build/locations.js.map +1 -1
- package/dist/build/pages.d.ts +3 -4
- package/dist/build/pages.d.ts.map +1 -1
- package/dist/build/pages.js +3 -4
- package/dist/build/pages.js.map +1 -1
- package/dist/core/lb-constants.d.ts +27 -24
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +103 -168
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/core/lb-types.d.ts +64 -77
- package/dist/core/lb-types.d.ts.map +1 -1
- package/dist/core/lb-types.js +40 -7
- package/dist/core/lb-types.js.map +1 -1
- package/dist/hub/lb-apply.d.ts +47 -37
- package/dist/hub/lb-apply.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +195 -199
- package/dist/hub/lb-apply.js.map +1 -1
- package/dist/hub/lb-hub.browser.d.ts +1 -1
- package/dist/hub/lb-hub.browser.d.ts.map +1 -1
- package/dist/hub/lb-hub.browser.js +410 -449
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/dist/server/lb-express.d.ts +5 -5
- package/dist/server/lb-express.d.ts.map +1 -1
- package/dist/server/lb-express.js +35 -66
- package/dist/server/lb-express.js.map +1 -1
- package/dist/server/lb-server.d.ts +77 -135
- package/dist/server/lb-server.d.ts.map +1 -1
- package/dist/server/lb-server.js +132 -79
- package/dist/server/lb-server.js.map +1 -1
- package/docs/TECHREF-1.0.md +908 -585
- package/docs/comparison.md +243 -185
- package/docs/prior-art.md +15 -14
- package/docs/reference/builder.md +9 -3
- package/docs/reference/chrome.md +107 -56
- package/docs/reference/custom-elements.md +291 -173
- package/docs/reference/data-binding.md +381 -374
- package/docs/reference/overview.md +12 -10
- package/docs/reference/page-files.md +164 -99
- package/docs/reference/server.md +2 -2
- package/docs/reference/widgets.md +104 -110
- package/docs/roadmap.md +32 -39
- package/docs/terms-of-art.md +57 -0
- package/docs/testing.md +97 -68
- package/docs/theory.md +92 -58
- package/docs/tutorials/010-pages-and-navigation.md +20 -12
- package/docs/tutorials/020-css.md +6 -3
- package/docs/tutorials/030-html-decomposition.md +9 -7
- package/docs/tutorials/040-displaying-data.md +30 -13
- package/docs/tutorials/{050-actions.md → 050-requests.md} +25 -15
- package/docs/tutorials/060-custom-element-code.md +17 -16
- package/docs/tutorials/065-conditional-rendering.md +34 -23
- package/docs/tutorials/070-displaying-a-list.md +29 -21
- package/docs/tutorials/072-inserting-into-a-list.md +24 -16
- package/docs/tutorials/074-deleting-from-a-list.md +9 -7
- package/docs/tutorials/076-updating-a-list-item.md +11 -10
- package/docs/tutorials/080-widget-requests.md +71 -43
- package/docs/tutorials/090-using-widget-libraries.md +22 -22
- package/docs/what-does-loadbare-extend.md +124 -0
- package/package.json +1 -1
- package/skills/loadbare-app/SKILL.md +201 -123
- package/skills/loadbare-app/references/TECHREF-1.0.md +908 -585
- package/skills/loadbare-app/references/builder.md +9 -3
- package/skills/loadbare-app/references/chrome.md +107 -56
- package/skills/loadbare-app/references/custom-elements.md +291 -173
- package/skills/loadbare-app/references/data-binding.md +381 -374
- package/skills/loadbare-app/references/overview.md +12 -10
- package/skills/loadbare-app/references/page-files.md +164 -99
- package/skills/loadbare-app/references/server.md +2 -2
- package/skills/loadbare-app/references/widgets.md +104 -110
- package/docs/analysis-accidental-complexity.md +0 -149
- package/docs/analysis-closed-set.md +0 -210
|
@@ -122,11 +122,17 @@ A tag with neither a script nor a definition in any origin is an error.
|
|
|
122
122
|
| `app.css` | Every stylesheet, concatenated |
|
|
123
123
|
| `pages.ts` | The `hub` the server passes to `hubRoutes` |
|
|
124
124
|
|
|
125
|
-
The builder expands the chrome and every page against the available
|
|
125
|
+
The builder expands the chrome and every page against the available
|
|
126
126
|
definitions — see [Custom Elements](./custom-elements.md#html) for the
|
|
127
127
|
substitution rules — wraps each expanded page in
|
|
128
|
-
`<template lb-page="<
|
|
129
|
-
|
|
128
|
+
`<template lb-page="<stub>">`, and splices them into the chrome's `<body>`.
|
|
129
|
+
It removes a page file's `<title>` and stamps its text on the page's
|
|
130
|
+
template as `lb-page-title`; see [The page title](./page-files.md#the-page-title).
|
|
131
|
+
It formats the result with Prettier when the application has it installed.
|
|
132
|
+
|
|
133
|
+
The builder checks the `lb-` attributes of the chrome and every page after
|
|
134
|
+
expansion, and stops on the first file with a problem; see
|
|
135
|
+
[The markup checks](./data-binding.md#the-markup-checks).
|
|
130
136
|
|
|
131
137
|
The builder writes `app.css` only when it finds a stylesheet, and `pages.ts`
|
|
132
138
|
only when some page has a `.requests.ts` or a `.queries.ts` file. Import `hub`
|
|
@@ -9,7 +9,7 @@ anywhere in the `src/` tree. Any directory will do.
|
|
|
9
9
|
|
|
10
10
|
## A complete chrome
|
|
11
11
|
|
|
12
|
-
Here is a minimal but
|
|
12
|
+
Here is a minimal but complete chrome for a typical app:
|
|
13
13
|
|
|
14
14
|
```html
|
|
15
15
|
<!-- src/chrome.html -->
|
|
@@ -24,18 +24,18 @@ Here is a minimal but fully complaint chrome for a typical app:
|
|
|
24
24
|
</head>
|
|
25
25
|
<body hidden>
|
|
26
26
|
<lb-hub>
|
|
27
|
-
<header lb-
|
|
27
|
+
<header lb-query="lb-url">
|
|
28
28
|
<h1>Membership Roster</h1>
|
|
29
|
-
<h2 lb-
|
|
29
|
+
<h2 lb-column="lb-page-label"></h2>
|
|
30
30
|
</header>
|
|
31
31
|
<nav>
|
|
32
|
-
<a href="/" lb-
|
|
33
|
-
<a href="/members" lb-
|
|
32
|
+
<a href="/" lb-url-link>Home</a>
|
|
33
|
+
<a href="/members" lb-url-link>Members</a>
|
|
34
34
|
<a href="https://example.org/">Our website</a>
|
|
35
35
|
</nav>
|
|
36
36
|
<main></main>
|
|
37
|
-
<dialog lb-unknown
|
|
38
|
-
The URL <span lb-
|
|
37
|
+
<dialog lb-url-unknown lb-query="lb-url">
|
|
38
|
+
The URL <span lb-column="lb-path"></span> is not in this app.
|
|
39
39
|
</dialog>
|
|
40
40
|
</lb-hub>
|
|
41
41
|
</body>
|
|
@@ -52,81 +52,133 @@ The chrome is plain HTML; nothing in it is generated or templated.
|
|
|
52
52
|
| A complete HTML document | Doctype, `<html>`, `<head>`, `<body>` |
|
|
53
53
|
| `<lb-hub>` inside `<body>` | The application's live element |
|
|
54
54
|
| An empty `<main>` inside `<lb-hub>` | Holds the current page |
|
|
55
|
-
| `<script src="/client.js" defer>` | Defines `<lb-hub>` and every other
|
|
55
|
+
| `<script src="/client.js" defer>` | Defines `<lb-hub>` and every other custom element |
|
|
56
56
|
|
|
57
57
|
Everything else is optional:
|
|
58
58
|
|
|
59
59
|
| Optional | Description |
|
|
60
60
|
|-------------------------------------------|---------------------------------------------|
|
|
61
61
|
| `<link rel="stylesheet" href="/app.css">` | The bundled stylesheet |
|
|
62
|
-
| `<a lb-
|
|
63
|
-
| `lb-
|
|
64
|
-
| `<dialog lb-unknown
|
|
65
|
-
| Custom elements | The chrome, decomposed into
|
|
62
|
+
| `<a lb-url-link>` | A link between pages |
|
|
63
|
+
| `lb-query="lb-url"` | Where the page is — see below |
|
|
64
|
+
| `<dialog lb-url-unknown>` | A message when a URL matches no page |
|
|
65
|
+
| Custom elements | The chrome, decomposed into element files |
|
|
66
66
|
| `<body hidden>` + a `<noscript>` fallback | Avoids a first-load blink — see below |
|
|
67
67
|
| Any other HTML | Header, footer, skip links, meta tags, etc. |
|
|
68
68
|
|
|
69
|
-
## Rules for writing chrome
|
|
69
|
+
## Rules for writing chrome
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
Put everything the user interacts with inside `<lb-hub>`. The hub normally
|
|
72
72
|
sits directly inside `<body>`, with banner, nav, footer and `<main>` inside
|
|
73
73
|
it, so Loadbare can act on all of them.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
[Query parms](./data-binding.md#query-parms). A bare `/` resolves to `index`, so the
|
|
79
|
-
landing page is the one named `index.page.html`. An anchor without
|
|
80
|
-
`lb-nav-link` is left alone and behaves like any other link.
|
|
75
|
+
The chrome's `<title>` is the document title until the first page shows.
|
|
76
|
+
From then on the hub sets the document title to the page's label; see
|
|
77
|
+
[The URL](#the-url).
|
|
81
78
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
path names no page. What it says is up to the chrome:
|
|
85
|
-
the dialog is a subtree like any other, and it displays where the page is by
|
|
86
|
-
naming the hub's own query, described next.
|
|
79
|
+
Put `lb-url-unknown` on a `<dialog>` inside `<lb-hub>`; the builder rejects
|
|
80
|
+
it anywhere else.
|
|
87
81
|
|
|
88
|
-
##
|
|
82
|
+
## The URL
|
|
89
83
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
row
|
|
93
|
-
shows a value — so a chrome displays the current page with no code at all:
|
|
84
|
+
The hub serves one query of its own, `lb-url`, of kind `row`, keyed by
|
|
85
|
+
`lb-path`. It lands on every element inside the hub that names it, the way a
|
|
86
|
+
server's row lands, so a chrome shows where the page is with no code:
|
|
94
87
|
|
|
95
88
|
```html
|
|
96
|
-
<header lb-
|
|
89
|
+
<header lb-query="lb-url">
|
|
97
90
|
<h1>Membership Roster</h1>
|
|
98
|
-
<h2 lb-
|
|
91
|
+
<h2 lb-column="lb-page-label"></h2>
|
|
99
92
|
</header>
|
|
100
93
|
```
|
|
101
94
|
|
|
102
|
-
|
|
|
103
|
-
|
|
104
|
-
| `
|
|
105
|
-
| `page-
|
|
95
|
+
| Column | Holds |
|
|
96
|
+
|-------------------|---------------------------------------------------------|
|
|
97
|
+
| `lb-path` | The path, such as `/members`. The row's key |
|
|
98
|
+
| `lb-page-label` | The page's title, or its stub when it has none |
|
|
99
|
+
| `lb-page-unknown` | `true` when no page's stub matches the path |
|
|
100
|
+
| Any other name | The query parm of that name, or empty when it is absent |
|
|
106
101
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
A path names a page by its stub: `/members` shows `members.page.html`, and
|
|
103
|
+
`/` shows `index.page.html`. A page's title is the text of the `<title>` its
|
|
104
|
+
page file carries; see [page files](./page-files.md#the-page-title). The hub
|
|
105
|
+
sets the document title to `lb-page-label` whenever it is not null, so the
|
|
106
|
+
tab and the browser history show the page.
|
|
112
107
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
subtree names it, so a chrome that displays no navigation is not warned
|
|
116
|
-
about a query with no scope.
|
|
108
|
+
`lb-url` is the one query a page may use that the server does not declare. A
|
|
109
|
+
page names it the same way, anywhere inside the hub.
|
|
117
110
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
111
|
+
### Links
|
|
112
|
+
|
|
113
|
+
Write `lb-url-link` on an `<a>` to move between pages:
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<nav>
|
|
117
|
+
<a href="/" lb-url-link>Home</a>
|
|
118
|
+
<a href="/members?team=Engines" lb-url-link>Engines</a>
|
|
119
|
+
</nav>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
On a plain primary click, the hub pushes a history entry for the `href`,
|
|
123
|
+
path and query string both, and shows the page it names. A click with a
|
|
124
|
+
modifier key or another button, and a link without `lb-url-link`, behave as
|
|
125
|
+
the browser has them behave. Back and Forward show the page at the URL they
|
|
126
|
+
arrive at.
|
|
127
|
+
|
|
128
|
+
### Query parms
|
|
129
|
+
|
|
130
|
+
A query parm is a column of `lb-url`. A control inside `lb-query="lb-url"`
|
|
131
|
+
that sends `lb-row-update` writes its value into the query string:
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<div lb-query="lb-url">
|
|
135
|
+
<select lb-column="team" lb-request="lb-row-update">
|
|
136
|
+
<option value="">Every team</option>
|
|
137
|
+
<option value="Engines">Engines</option>
|
|
138
|
+
</select>
|
|
139
|
+
</div>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
On `change`, the hub sets that parm and keeps every other, and takes the
|
|
143
|
+
parm out when the value is empty. It replaces the current history entry, and
|
|
144
|
+
pushes one instead when the element carrying `lb-request` also carries
|
|
145
|
+
`lb-url-push`:
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<input lb-column="q" lb-request="lb-row-update" lb-url-push />
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The hub answers the request itself, with no round trip, then reloads the
|
|
152
|
+
page's queries at the new URL. The page stays in place, and rows that come
|
|
153
|
+
back keep their place.
|
|
154
|
+
|
|
155
|
+
A control whose column the URL does not carry lands empty, so every control
|
|
156
|
+
inside `lb-query="lb-url"` shows what the address bar says, after a reload
|
|
157
|
+
and after Back alike.
|
|
158
|
+
|
|
159
|
+
The hub sends the query parms with every round trip, and the server hands
|
|
160
|
+
them to `contextFor`; see [the Express server](./server.md#database-layer).
|
|
161
|
+
A handler moves the URL by returning `url()`, when only the server knows the
|
|
162
|
+
new value; see [page files](./page-files.md#moving-the-url).
|
|
163
|
+
|
|
164
|
+
### An unknown page
|
|
165
|
+
|
|
166
|
+
A path that names no page shows the unknown-page dialog. Write it in the
|
|
167
|
+
chrome as a `<dialog>` carrying `lb-url-unknown`, and name `lb-url` on it to
|
|
168
|
+
show the path:
|
|
121
169
|
|
|
122
170
|
```html
|
|
123
|
-
<dialog lb-unknown
|
|
124
|
-
The URL <span lb-
|
|
171
|
+
<dialog lb-url-unknown lb-query="lb-url">
|
|
172
|
+
The URL <span lb-column="lb-path"></span> is not in this app.
|
|
125
173
|
</dialog>
|
|
126
174
|
```
|
|
127
175
|
|
|
128
|
-
|
|
129
|
-
|
|
176
|
+
When no page's stub matches the path, `lb-page-unknown` is `true`,
|
|
177
|
+
`lb-page-label` is null, `<main>` keeps the page it had, and the hub calls
|
|
178
|
+
`showModal()` on the dialog.
|
|
179
|
+
|
|
180
|
+
`@loadbare/widgets` ships this dialog as `<lb-unknown-page>`, for a chrome
|
|
181
|
+
that would rather write one tag; see
|
|
130
182
|
[The Basic Widget Library](./widgets.md#lb-unknown-page).
|
|
131
183
|
|
|
132
184
|
## Preventing the first-load blink
|
|
@@ -137,10 +189,9 @@ visible flash: the chrome appears first, then `<main>`'s real content pops in
|
|
|
137
189
|
a moment later and shifts everything around it.
|
|
138
190
|
|
|
139
191
|
`<body hidden>` avoids this by hiding the whole document, not just `<main>`,
|
|
140
|
-
until the hub has something to show. `<lb-hub>` un-hides `<body>` itself
|
|
141
|
-
first
|
|
142
|
-
|
|
143
|
-
intermediate state to flash.
|
|
192
|
+
until the hub has something to show. `<lb-hub>` un-hides `<body>` itself
|
|
193
|
+
once it has put the first page in `<main>`, so the chrome and the first
|
|
194
|
+
page's markup appear together, already in their final layout.
|
|
144
195
|
|
|
145
196
|
Hiding `<main>` alone doesn't work: an empty `<main>` already renders at zero
|
|
146
197
|
height, so hiding it changes nothing visible. The pop-in comes from the
|