@loadbare/app 0.12.0 → 0.13.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/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +57 -1
- package/dist/build/assemble.js.map +1 -1
- package/dist/build/cli.js +2 -1
- package/dist/build/cli.js.map +1 -1
- package/dist/build/elements.d.ts +9 -1
- package/dist/build/elements.d.ts.map +1 -1
- package/dist/build/elements.js +50 -0
- package/dist/build/elements.js.map +1 -1
- package/dist/build/origins.d.ts +2 -0
- package/dist/build/origins.d.ts.map +1 -1
- package/dist/build/origins.js +1 -1
- package/dist/build/origins.js.map +1 -1
- package/dist/core/lb-constants.d.ts +24 -1
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +71 -0
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/core/lb-types.d.ts +47 -18
- package/dist/core/lb-types.d.ts.map +1 -1
- package/dist/core/lb-types.js +74 -11
- package/dist/core/lb-types.js.map +1 -1
- package/dist/hub/lb-apply.d.ts +37 -15
- package/dist/hub/lb-apply.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +598 -56
- package/dist/hub/lb-apply.js.map +1 -1
- package/dist/hub/lb-hub.browser.d.ts.map +1 -1
- package/dist/hub/lb-hub.browser.js +61 -14
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/dist/server/lb-express.d.ts +6 -4
- package/dist/server/lb-express.d.ts.map +1 -1
- package/dist/server/lb-express.js +32 -14
- package/dist/server/lb-express.js.map +1 -1
- package/dist/server/lb-server.d.ts +49 -10
- package/dist/server/lb-server.d.ts.map +1 -1
- package/dist/server/lb-server.js +76 -34
- package/dist/server/lb-server.js.map +1 -1
- package/docs/TECHREF-1.0.md +292 -92
- package/docs/comparison.md +11 -9
- package/docs/possible-ideas.md +188 -0
- package/docs/reference/chrome.md +7 -1
- package/docs/reference/custom-elements.md +37 -38
- package/docs/reference/data-binding.md +102 -13
- package/docs/reference/page-files.md +25 -16
- package/docs/reference/server.md +4 -0
- package/docs/reference/widgets.md +94 -24
- package/docs/roadmap.md +10 -6
- package/docs/testing.md +21 -10
- package/package.json +2 -3
- package/skills/loadbare-app/SKILL.md +43 -24
- package/skills/loadbare-app/references/TECHREF-1.0.md +292 -92
- package/skills/loadbare-app/references/chrome.md +7 -1
- package/skills/loadbare-app/references/custom-elements.md +37 -38
- package/skills/loadbare-app/references/data-binding.md +102 -13
- package/skills/loadbare-app/references/page-files.md +25 -16
- package/skills/loadbare-app/references/server.md +4 -0
- package/skills/loadbare-app/references/widgets.md +94 -24
|
@@ -278,7 +278,10 @@ A custom element reads `lb-` attributes and never assigns one. The developer
|
|
|
278
278
|
writes them in markup, and the hub and the builder write their stamps.
|
|
279
279
|
|
|
280
280
|
Loadbare reserves method names beginning with `lb` on a custom element, for
|
|
281
|
-
the methods it calls; see [Holding rows](#holding-rows).
|
|
281
|
+
the methods it calls; see [Holding rows](#holding-rows). The build refuses
|
|
282
|
+
a script that declares a method, accessor or field whose name is `lb`, a
|
|
283
|
+
capital, and anything else Loadbare does not call, so a misspelled
|
|
284
|
+
`lbRowLanded` fails the build rather than never being called.
|
|
282
285
|
|
|
283
286
|
### What the hub and an element say to each other
|
|
284
287
|
|
|
@@ -286,9 +289,9 @@ Each direction has one mechanism for each kind of message:
|
|
|
286
289
|
|
|
287
290
|
| Direction | What | How | Today |
|
|
288
291
|
|----------------|--------------------------------------------|-----------------------------|-------|
|
|
289
|
-
| Hub to element | State that lasts | An attribute the hub stamps | `lb-column-value`, `lb-key-value`, `lb-query-row-count`, `lb-request-pending`, `lb-request-error` |
|
|
292
|
+
| Hub to element | State that lasts | An attribute the hub stamps | `lb-column-value`, `lb-key-value`, `lb-query-row-count`, `lb-group-*`, `lb-row-*`, `lb-request-pending`, `lb-request-error` |
|
|
290
293
|
| Hub to element | State the platform already names | A property | A control's `value` |
|
|
291
|
-
| Hub to element | Work the hub needs done now, while landing | An optional `lb` method | `
|
|
294
|
+
| Hub to element | Work the hub needs done now, while landing | An optional `lb` method | `lbRowsLanded` |
|
|
292
295
|
| Hub to element | A moment an element started | A bubbling event | `lb-request-done` |
|
|
293
296
|
| Element to hub | A moment | A bubbling event | `lb-request`, and `change`, `click` and `submit` |
|
|
294
297
|
|
|
@@ -329,7 +332,7 @@ So each kind of work has one place:
|
|
|
329
332
|
reads no attribute and no child: an element made with
|
|
330
333
|
`document.createElement` has neither when it runs.
|
|
331
334
|
2. **A child is looked up when it is needed**, in a handler, a getter,
|
|
332
|
-
|
|
335
|
+
or `lbRowsLanded`, and never held from setup.
|
|
333
336
|
3. **`connectedCallback` runs on every move**, so it is written to run
|
|
334
337
|
again. It rearranges the element's own children into a state it checks
|
|
335
338
|
for first, or adds a listener to `document` or `window`, which
|
|
@@ -505,34 +508,32 @@ outside the document, and no ancestor it had there hears it.
|
|
|
505
508
|
|
|
506
509
|
### Holding rows
|
|
507
510
|
|
|
508
|
-
The hub lands every row template itself
|
|
509
|
-
|
|
510
|
-
|
|
511
|
+
The hub lands every row template itself, places every row by the query's
|
|
512
|
+
order, and builds every group the markup's group templates describe; see
|
|
513
|
+
[Order](./data-binding.md#order) and [Groups](./data-binding.md#groups). A
|
|
514
|
+
plain element carrying `lb-query` with a row template inside it needs no
|
|
515
|
+
code, so a custom element holds rows only to do something with them once
|
|
516
|
+
they land.
|
|
511
517
|
|
|
512
|
-
A custom element carrying `lb-query` and a row template may implement
|
|
513
|
-
optional
|
|
518
|
+
A custom element carrying `lb-query` and a row template may implement one
|
|
519
|
+
optional method, which the hub calls:
|
|
514
520
|
|
|
515
521
|
```ts
|
|
516
|
-
import type { RowsHost
|
|
517
|
-
|
|
518
|
-
class SortedList extends HTMLElement implements RowsHost {
|
|
519
|
-
lbPlaceRow(el: Element, row: Row, template: HTMLTemplateElement) {
|
|
520
|
-
// Where this live row goes. Called with the live row detached, on its
|
|
521
|
-
// first appearance and again whenever all rows decide the order.
|
|
522
|
-
}
|
|
522
|
+
import type { RowsHost } from "@loadbare/app/types";
|
|
523
|
+
import { ATTR_ROW_REQUESTED, REQUESTED_CREATED } from "@loadbare/app/constants";
|
|
523
524
|
|
|
525
|
+
class ScrollingList extends HTMLElement implements RowsHost {
|
|
524
526
|
lbRowsLanded() {
|
|
525
|
-
// Once, after the rows have landed
|
|
526
|
-
|
|
527
|
-
|
|
527
|
+
// Once, after the rows have landed, every row placed and stamped.
|
|
528
|
+
this.querySelector(`[${ATTR_ROW_REQUESTED}="${REQUESTED_CREATED}"]`)
|
|
529
|
+
?.scrollIntoView({ block: "nearest" });
|
|
528
530
|
}
|
|
529
531
|
}
|
|
530
532
|
```
|
|
531
533
|
|
|
532
|
-
| Method | The hub calls it
|
|
533
|
-
|
|
534
|
-
| `
|
|
535
|
-
| `lbRowsLanded` | After the rows land |
|
|
534
|
+
| Method | The hub calls it |
|
|
535
|
+
|----------------|-------------------------------------------------------|
|
|
536
|
+
| `lbRowsLanded` | After the rows land, with every row placed and stamped |
|
|
536
537
|
|
|
537
538
|
Everything else is the hub's:
|
|
538
539
|
|
|
@@ -540,25 +541,23 @@ Everything else is the hub's:
|
|
|
540
541
|
|-------------|----------------------------------------------------------|
|
|
541
542
|
| Cloning | Clones the row template once per new key |
|
|
542
543
|
| Matching | Fills the live row already showing that key |
|
|
543
|
-
|
|
|
544
|
-
|
|
|
544
|
+
| Placing | Places every live row by the query's order |
|
|
545
|
+
| Grouping | Builds a group where the order breaks, and removes it with its last row |
|
|
546
|
+
| Removing | Marks the live rows the response says are gone as leaving, and removes them |
|
|
547
|
+
| Stamping | Stamps each live row with `lb-row-live`, `lb-key-value`, and what happened to it |
|
|
545
548
|
| Counting | Stamps `lb-query-row-count` with the number of live rows |
|
|
546
549
|
|
|
547
|
-
`
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
different placements over the same landing.
|
|
550
|
+
`lb-options.browser.ts` and `lb-table.browser.ts` in
|
|
551
|
+
[`@loadbare/widgets`](./widgets.md) are two uses of `lbRowsLanded`: one
|
|
552
|
+
gives each option and `<optgroup>` what landing does not, a value and a
|
|
553
|
+
label, and the other scrolls to the row the page's request created or
|
|
554
|
+
moved.
|
|
553
555
|
|
|
554
556
|
A custom element the builder shipped absent under `lb-show` has not
|
|
555
|
-
upgraded while its column is off,
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
`lbRowsLanded` runs. Once upgraded it stays so: when its branch goes away and
|
|
560
|
-
comes back, it has placed every row that landed meanwhile, and nothing is
|
|
561
|
-
landed again.
|
|
557
|
+
upgraded while its column is off, and the hub places the rows that land on
|
|
558
|
+
it then as it places any. When the column first turns on and the element
|
|
559
|
+
upgrades, the hub lands the query's last answer on it again, as all rows,
|
|
560
|
+
so `lbRowsLanded` runs.
|
|
562
561
|
|
|
563
562
|
A custom element that walks its own rows finds them with `LIVE_ROW` from
|
|
564
563
|
`@loadbare/app/constants`, never by `lb-key-value`: an element a `row` lands
|
|
@@ -153,9 +153,9 @@ places it immediately before the template:
|
|
|
153
153
|
```
|
|
154
154
|
|
|
155
155
|
The hub matches each row to a live row by its key. All rows decide
|
|
156
|
-
membership
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
membership: a live row whose key did not arrive leaves. A patch changes only
|
|
157
|
+
the rows it names, and every other live row keeps its content. The hub
|
|
158
|
+
places every live row by the query's order; see [Order](#order).
|
|
159
159
|
|
|
160
160
|
A key is unique within a query. Two rows with one key in the same answer,
|
|
161
161
|
or two live rows showing one key, are reported on the console.
|
|
@@ -163,10 +163,101 @@ or two live rows showing one key, are reported on the console.
|
|
|
163
163
|
A live row's root counts as a column when it carries `lb-column`, which is
|
|
164
164
|
how an `<option>`, whose content is text, shows the column it is.
|
|
165
165
|
|
|
166
|
-
A custom element that carries `lb-query` and a row template
|
|
167
|
-
|
|
168
|
-
[
|
|
169
|
-
|
|
166
|
+
A custom element that carries `lb-query` and a row template reacts to the
|
|
167
|
+
rows once they land; see [Holding rows](./custom-elements.md#holding-rows)
|
|
168
|
+
and [The Basic Widget Library](./widgets.md).
|
|
169
|
+
|
|
170
|
+
### Order
|
|
171
|
+
|
|
172
|
+
A `rows` query declares its order with the query, as columns separated by
|
|
173
|
+
commas, each descending when written after `-`:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
roster: rows("id", (ctx) => ctx.db.members(), { order: "team,name" }),
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The query parm `lb-order-<query>` replaces it for that query, so a control
|
|
180
|
+
inside `lb-query="lb-url"` writing that parm re-sorts the rows the hub
|
|
181
|
+
already has, with no round trip. With no order, rows show in the order they
|
|
182
|
+
arrived, and a patch's new rows go last.
|
|
183
|
+
|
|
184
|
+
Values compare by their JSON type: numbers numerically, strings as the
|
|
185
|
+
user's language orders them, `false` before `true`, and `null` last. A
|
|
186
|
+
number sent as a string sorts as a string. Rows that compare equal keep the
|
|
187
|
+
order they arrived in. A row moves only when the order puts it somewhere
|
|
188
|
+
else.
|
|
189
|
+
|
|
190
|
+
A query that pages or limits its rows reads the parm itself and declares
|
|
191
|
+
`serverSortedByUrl: true`, so a change of order loads the page again.
|
|
192
|
+
|
|
193
|
+
### Groups
|
|
194
|
+
|
|
195
|
+
A group is a run of rows sharing the order's leading term. Write a
|
|
196
|
+
`<template lb-group>` where the row template goes, holding the group's
|
|
197
|
+
heading and one nested `<template>`: the next group template, or the row
|
|
198
|
+
template. The nth group template breaks on the order's nth term.
|
|
199
|
+
|
|
200
|
+
```html
|
|
201
|
+
<ul lb-query="roster">
|
|
202
|
+
<template lb-group>
|
|
203
|
+
<li>
|
|
204
|
+
<h3 lb-column="team"></h3>
|
|
205
|
+
<ul>
|
|
206
|
+
<template><li lb-column="name"></li></template>
|
|
207
|
+
</ul>
|
|
208
|
+
</li>
|
|
209
|
+
</template>
|
|
210
|
+
</ul>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The group's contents land immediately before its nested template. When that
|
|
214
|
+
template is inside the heading's element, the contents land inside it; when
|
|
215
|
+
it is beside the heading, they land after it. `<tbody>` and `<optgroup>` do
|
|
216
|
+
not nest, so a table's deeper levels are heading rows. Content after the
|
|
217
|
+
nested template is the group's footer.
|
|
218
|
+
|
|
219
|
+
A heading is filled from its group's first row, so it may show a column
|
|
220
|
+
other than the one the group breaks on. The hub stamps each top-level
|
|
221
|
+
element of a group with `lb-group-live`, `lb-group-column` and
|
|
222
|
+
`lb-group-value`. A row creates its group, and a group leaves with its last
|
|
223
|
+
row.
|
|
224
|
+
|
|
225
|
+
### Aggregates
|
|
226
|
+
|
|
227
|
+
`lb-count`, `lb-sum="col"`, `lb-avg="col"`, `lb-min="col"` and
|
|
228
|
+
`lb-max="col"` set an element from the rows of the nearest group around it,
|
|
229
|
+
or of the whole list outside any group:
|
|
230
|
+
|
|
231
|
+
```html
|
|
232
|
+
<tr><td><span lb-count></span> people</td><td lb-sum="salary"></td></tr>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
A sum and an average are exact, read from JSON numbers and from strings
|
|
236
|
+
holding a plain decimal. `null` and empty values are left out. The result
|
|
237
|
+
lands unformatted, and covers the rows the browser holds.
|
|
238
|
+
|
|
239
|
+
### What happened to a row
|
|
240
|
+
|
|
241
|
+
Every change to a list is one a stylesheet can see:
|
|
242
|
+
|
|
243
|
+
| Attribute | Means |
|
|
244
|
+
| ------------------ | ------------------------------------------------------ |
|
|
245
|
+
| `lb-row-created` | Created when the hub last touched the row |
|
|
246
|
+
| `lb-row-changed` | Its values changed when the hub last touched it |
|
|
247
|
+
| `lb-row-moved` | The order put it somewhere else when last touched |
|
|
248
|
+
| `lb-row-requested` | `created`, `changed` or `moved` by this page's request |
|
|
249
|
+
| `lb-row-leaving` | A row on its way out |
|
|
250
|
+
| `lb-group-leaving` | A group on its way out |
|
|
251
|
+
|
|
252
|
+
A row that leaves loses `lb-row-live`, takes `inert`, and is removed once
|
|
253
|
+
its animations finish, at once when there are none. A moved row moves, and
|
|
254
|
+
a copy stays behind where it was, leaving. `lb-row-requested` is cleared at
|
|
255
|
+
every landing; the others when the hub next touches the row.
|
|
256
|
+
|
|
257
|
+
```css
|
|
258
|
+
[lb-row-created] { animation: arrive 200ms; }
|
|
259
|
+
[lb-row-leaving] { animation: depart 200ms forwards; }
|
|
260
|
+
```
|
|
170
261
|
|
|
171
262
|
### What arrives later
|
|
172
263
|
|
|
@@ -174,16 +265,14 @@ The hub keeps each query's last answer until the page changes, with any
|
|
|
174
265
|
patch since applied to it. An element that names a query and arrives after
|
|
175
266
|
that query's answer is filled from what was kept, at the end of the landing
|
|
176
267
|
that follows its arrival. Such an element is a picker in a new live row, or
|
|
177
|
-
scaffolding
|
|
268
|
+
scaffolding around rows, such as a group's heading or a ghost row. So
|
|
178
269
|
a query nested in another query's rows need not land again, or land after
|
|
179
270
|
the outer query, for a new outer row to show its choices.
|
|
180
271
|
|
|
181
272
|
A custom element the builder shipped absent has not upgraded while its
|
|
182
|
-
`lb-show` column is off
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
table that groups its rows can sit under `lb-show`. See
|
|
186
|
-
[Holding rows](./custom-elements.md#holding-rows).
|
|
273
|
+
`lb-show` column is off. When the column first turns on and the element
|
|
274
|
+
upgrades, the hub lands the kept answer on it again, so its `lbRowsLanded`
|
|
275
|
+
runs. See [Holding rows](./custom-elements.md#holding-rows).
|
|
187
276
|
|
|
188
277
|
Nothing is answered from what the hub kept: a request always goes to the
|
|
189
278
|
server, and a query re-runs only when a response names it. A patch that
|
|
@@ -48,7 +48,8 @@ page touches that page's files.
|
|
|
48
48
|
## HTML
|
|
49
49
|
|
|
50
50
|
Write the page as a fragment. The fragment lands in `<main>`, which
|
|
51
|
-
[chrome.html](./chrome.md) supplies.
|
|
51
|
+
[chrome.html](./chrome.md) supplies. A page carries no `<main>` and no
|
|
52
|
+
`<lb-hub>` of its own; the builder rejects one that does.
|
|
52
53
|
|
|
53
54
|
```html
|
|
54
55
|
<!-- src/pages/about.page.html -->
|
|
@@ -89,14 +90,18 @@ export const queries: Queries = {
|
|
|
89
90
|
page: "directory",
|
|
90
91
|
count: String(await ctx.db.visitCount()),
|
|
91
92
|
})),
|
|
92
|
-
directory: rows("id", (ctx) => ctx.db.directory()),
|
|
93
|
+
directory: rows("id", (ctx) => ctx.db.directory(), { order: "name" }),
|
|
93
94
|
};
|
|
94
95
|
```
|
|
95
96
|
|
|
96
|
-
| Declared with
|
|
97
|
-
|
|
98
|
-
| `row(key, run)`
|
|
99
|
-
| `rows(key, run)` | All its rows, an array of objects
|
|
97
|
+
| Declared with | Answers with |
|
|
98
|
+
|----------------------------|-------------------------------------------|
|
|
99
|
+
| `row(key, run)` | One row, an object |
|
|
100
|
+
| `rows(key, run, options)` | All its rows, an array of objects |
|
|
101
|
+
|
|
102
|
+
`options` are a `rows` query's order: `order`, the columns the hub places
|
|
103
|
+
its rows by, and `serverSortedByUrl`, set when the query reads the user's
|
|
104
|
+
order parm itself. See [Order](./data-binding.md#order).
|
|
100
105
|
|
|
101
106
|
`key` names the column that identifies a row. Give every row that column,
|
|
102
107
|
including a `row` query's: an aggregate row answers with a constant key. The
|
|
@@ -109,8 +114,8 @@ page that needs the same data as one row and as a set declares two queries.
|
|
|
109
114
|
The hub hands each value to the browser untouched, so what a number, a date
|
|
110
115
|
or a null looks like is decided here, in the query.
|
|
111
116
|
|
|
112
|
-
Return the full answer every time
|
|
113
|
-
|
|
117
|
+
Return the full answer every time. With no `order`, the rows show in the
|
|
118
|
+
order they are returned. Sending only what changed is a request's job — see
|
|
114
119
|
[refresh and patch](#refresh-and-patch).
|
|
115
120
|
|
|
116
121
|
## Requests
|
|
@@ -120,7 +125,7 @@ optional:
|
|
|
120
125
|
|
|
121
126
|
| Key | Runs |
|
|
122
127
|
|---------------|--------------------------------------------------------|
|
|
123
|
-
| `onPageEnter` | Before the page's queries, when the page loads
|
|
128
|
+
| `onPageEnter` | Before the page's queries, when the page loads; may move the URL |
|
|
124
129
|
| `handlers` | The page's declared requests, by request name |
|
|
125
130
|
| `crud` | The requests Loadbare provides, by query name |
|
|
126
131
|
|
|
@@ -150,6 +155,12 @@ export const requests: Requests = {
|
|
|
150
155
|
|
|
151
156
|
Declare no refresh set here. The page's queries run afterward.
|
|
152
157
|
|
|
158
|
+
It may return `url()` instead, to move the page to other query parms before
|
|
159
|
+
anything shows, as restoring the filters and order the user last had does.
|
|
160
|
+
The page loads there in the same round trip, and that load does not follow
|
|
161
|
+
`onPageEnter` again. A `url()` leading to the parms already in hand is
|
|
162
|
+
ignored. See [Moving the URL](#moving-the-url).
|
|
163
|
+
|
|
153
164
|
### handlers
|
|
154
165
|
|
|
155
166
|
Declare a request under the name the HTML gives `lb-request`. Pair what it
|
|
@@ -240,16 +251,14 @@ queries:
|
|
|
240
251
|
|
|
241
252
|
Return a patch for a change the request knows the extent of — one row added,
|
|
242
253
|
one row dropped, one row edited — and leave `refresh` empty. A refreshed
|
|
243
|
-
`rows` query sends every row
|
|
244
|
-
each element and takes focus from the control the user is in.
|
|
254
|
+
`rows` query sends every row to say what one row could.
|
|
245
255
|
|
|
246
256
|
A change that seems to need a refresh usually has a patch:
|
|
247
257
|
|
|
248
|
-
- A
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
[`lb-table`](./widgets.md#lb-table) does by `data-sort`.
|
|
258
|
+
- A row whose position changes: the hub places it by the query's
|
|
259
|
+
[order](./data-binding.md#order).
|
|
260
|
+
- A group that appears or goes: the hub makes a group with its first row
|
|
261
|
+
and removes it with its last, so no row stands in for an empty one.
|
|
253
262
|
- A row whose other columns change with the edit: re-read the row and patch
|
|
254
263
|
it.
|
|
255
264
|
- Rows the database removes with a deleted one: select their keys before the
|
|
@@ -91,6 +91,10 @@ TypeScript types itself. `dist/pages.ts` imports each `.requests.ts` and
|
|
|
91
91
|
`.queries.ts` file by its full name, extension included, because Node looks
|
|
92
92
|
for exactly the path an import names.
|
|
93
93
|
|
|
94
|
+
The `hub` it exports comes from `createHub`, the only implementation of
|
|
95
|
+
the `Hub` interface. That interface may gain members in any release, so an
|
|
96
|
+
application never implements it.
|
|
97
|
+
|
|
94
98
|
Enable `allowImportingTsExtensions` in the application's `tsconfig.json`
|
|
95
99
|
when `tsc` type-checks the server. Without it, `tsc` rejects the `.ts`
|
|
96
100
|
extensions in `dist/pages.ts`:
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# The Basic Widget Library
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`lb-unknown-page
|
|
3
|
+
Ten widgets: `lb-input`, `lb-select`, `lb-options`, `lb-picker`, `lb-table`,
|
|
4
|
+
`lb-unknown-page`, `lb-confirm`, `lb-form`, `lb-insert-dialog` and
|
|
5
|
+
`lb-master`. Every one of them is an ordinary custom element, written
|
|
5
6
|
against the contracts in [Custom Elements](./custom-elements.md#html) for its
|
|
6
7
|
definition and [Custom Elements](./custom-elements.md#code) for its class.
|
|
7
8
|
|
|
@@ -43,6 +44,7 @@ write the same edit twice.
|
|
|
43
44
|
| Parameter | Fills |
|
|
44
45
|
|----------------|----------------------------------|
|
|
45
46
|
| `exp-label` | The visible `<label>` text |
|
|
47
|
+
| `exp-type` | The input's `type`, `text` when absent |
|
|
46
48
|
| `exp-readonly` | The input's `readonly` attribute |
|
|
47
49
|
|
|
48
50
|
## `lb-select`
|
|
@@ -67,9 +69,7 @@ writes the row template inside the widget:
|
|
|
67
69
|
|
|
68
70
|
```html
|
|
69
71
|
<lb-options lb-query="statuses" lb-column="status" lb-request="lb-row-update" exp-label="Status">
|
|
70
|
-
<template
|
|
71
|
-
<option lb-column="label"></option>
|
|
72
|
-
</template>
|
|
72
|
+
<template><option lb-column="label"></option></template>
|
|
73
73
|
</lb-options>
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -79,9 +79,15 @@ writes the row template inside the widget:
|
|
|
79
79
|
|
|
80
80
|
- Each option's `value` is its row's key, the `lb-key-value` the hub stamps
|
|
81
81
|
on the live row, so the widget holds a key and shows a label.
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
- A group template holding an `<optgroup>` puts the options in groups, one
|
|
83
|
+
per run of the query's order's leading term. The widget labels each
|
|
84
|
+
`<optgroup>` from the `lb-group-value` the hub stamps on it:
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<template lb-group>
|
|
88
|
+
<optgroup><template><option lb-column="label"></option></template></optgroup>
|
|
89
|
+
</template>
|
|
90
|
+
```
|
|
85
91
|
- Its `value` selects the option with that key, including an option that
|
|
86
92
|
arrives after the value did.
|
|
87
93
|
|
|
@@ -100,7 +106,6 @@ one option showing one column:
|
|
|
100
106
|
lb-request="lb-row-update"
|
|
101
107
|
exp-label="Status"
|
|
102
108
|
exp-column="label"
|
|
103
|
-
exp-group="category"
|
|
104
109
|
></lb-picker>
|
|
105
110
|
```
|
|
106
111
|
|
|
@@ -108,10 +113,9 @@ one option showing one column:
|
|
|
108
113
|
|--------------|-----------------------------------------|
|
|
109
114
|
| `exp-label` | The visible `<label>` text |
|
|
110
115
|
| `exp-column` | The column each option shows |
|
|
111
|
-
| `exp-group` | The row template's `data-group` |
|
|
112
116
|
|
|
113
|
-
An option built from two columns,
|
|
114
|
-
`lb-options` with the page's own
|
|
117
|
+
An option built from two columns, a row with a second element, or options
|
|
118
|
+
in groups, is `lb-options` with the page's own templates.
|
|
115
119
|
|
|
116
120
|
## `lb-table`
|
|
117
121
|
|
|
@@ -123,11 +127,14 @@ row, the row template, and optionally a footer, each as a `<template>`:
|
|
|
123
127
|
<template lb-exp-template="head">
|
|
124
128
|
<tr><th>Date</th><th>Amount</th></tr>
|
|
125
129
|
</template>
|
|
126
|
-
<template
|
|
127
|
-
<tr><
|
|
130
|
+
<template lb-group>
|
|
131
|
+
<tr><th colspan="2" lb-column="month"></th></tr>
|
|
132
|
+
<template>
|
|
133
|
+
<tr><td lb-column="date"></td><td lb-column="amount"></td></tr>
|
|
134
|
+
</template>
|
|
128
135
|
</template>
|
|
129
136
|
<template lb-exp-template="foot">
|
|
130
|
-
<tr
|
|
137
|
+
<tr><td>Total</td><td lb-sum="amount"></td></tr>
|
|
131
138
|
</template>
|
|
132
139
|
</lb-table>
|
|
133
140
|
```
|
|
@@ -140,15 +147,78 @@ row, the row template, and optionally a footer, each as a `<template>`:
|
|
|
140
147
|
|-----------------------------------|-----------------------------------------|
|
|
141
148
|
| `<template lb-exp-template="head">` | The `<thead>` |
|
|
142
149
|
| `<template lb-exp-template="foot">` | The `<tfoot>` |
|
|
143
|
-
| Any other `<template>` | The row template, in the `<tbody>`
|
|
144
|
-
|
|
145
|
-
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
| Any other `<template>` | The row or group template, in the `<tbody>` |
|
|
151
|
+
|
|
152
|
+
- The hub places the rows by the query's order and builds its groups. The
|
|
153
|
+
rows land in the one `<tbody>`, so a group here is a heading row with its
|
|
154
|
+
rows after it.
|
|
155
|
+
- The footer is not a row of `ledger`. An aggregate there covers every row;
|
|
156
|
+
a figure that is not a sum of the rows, such as a budget, is a `<tr>`
|
|
157
|
+
naming a `row` query of its own.
|
|
158
|
+
- A `<template lb-exp-template="ghost">` is a blank row for entering a new
|
|
159
|
+
one, in a `<tbody>` of its own. The widget joins its controls to a form
|
|
160
|
+
outside the table, since a `<form>` cannot wrap a `<tr>`, and puts the
|
|
161
|
+
cursor back in it once an insert from it succeeds.
|
|
162
|
+
- After rows land, the widget scrolls the row the page's own request created
|
|
163
|
+
or moved into view.
|
|
164
|
+
|
|
165
|
+
## `lb-confirm`
|
|
166
|
+
|
|
167
|
+
A button that asks before it sends. The page writes the question inside the
|
|
168
|
+
tag, and the request goes on the dialog's confirm button, so nothing reaches
|
|
169
|
+
the hub until the user says yes:
|
|
170
|
+
|
|
171
|
+
```html
|
|
172
|
+
<lb-confirm exp-label="Delete" exp-request="lb-row-delete">
|
|
173
|
+
Delete <b lb-column="name"></b>?
|
|
174
|
+
</lb-confirm>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
| Parameter | Fills |
|
|
178
|
+
|---------------|--------------------------------------------------|
|
|
179
|
+
| `exp-label` | The text of the button that opens the dialog |
|
|
180
|
+
| `exp-request` | The confirm button's `lb-request` |
|
|
181
|
+
| `exp-confirm` | The confirm button's text, `Confirm` when absent |
|
|
182
|
+
|
|
183
|
+
The widget closes the dialog once `lb-request-done` says the request
|
|
184
|
+
succeeded, and leaves it open on a refusal.
|
|
185
|
+
|
|
186
|
+
## `lb-form`
|
|
187
|
+
|
|
188
|
+
A `<form>` over one row's controls. A row with a key saves each control's
|
|
189
|
+
column on `change`; a row whose key is empty is new, and the widget stops an
|
|
190
|
+
`lb-row-update` that carries no key, so its controls wait for a submit.
|
|
191
|
+
|
|
192
|
+
| Parameter | Fills |
|
|
193
|
+
|-----------|-----------------|
|
|
194
|
+
| `exp-id` | The form's `id` |
|
|
195
|
+
|
|
196
|
+
## `lb-insert-dialog`
|
|
197
|
+
|
|
198
|
+
A row entered in a modal dialog, written once outside every row and opened
|
|
199
|
+
with `commandfor` and `command="show-modal"`. Save is the form's
|
|
200
|
+
`lb-row-insert`; on success the widget chooses the new row in the nearest
|
|
201
|
+
`lb-options` around the button that opened it, and closes. The handler
|
|
202
|
+
answers with a patch holding the new row.
|
|
203
|
+
|
|
204
|
+
| Parameter | Fills |
|
|
205
|
+
|-------------|---------------------------------------------------|
|
|
206
|
+
| `exp-id` | The dialog's `id` |
|
|
207
|
+
| `exp-title` | The dialog's heading |
|
|
208
|
+
| `exp-query` | The form's `lb-query`, which it inserts into |
|
|
209
|
+
| `exp-save` | The Save button's text, `Save` when absent |
|
|
210
|
+
|
|
211
|
+
## `lb-master`
|
|
212
|
+
|
|
213
|
+
A set, one of its rows, and the buttons that act on the set: Copy, Delete,
|
|
214
|
+
Save new and Cancel, each shown only for a row on record or a new one. A
|
|
215
|
+
definition only, built from `lb-form` and `lb-confirm`. Copy sends `copy`, a
|
|
216
|
+
request the page declares.
|
|
217
|
+
|
|
218
|
+
| Parameter | Fills |
|
|
219
|
+
|---------------|--------------------------------------------|
|
|
220
|
+
| `exp-row` | The `lb-query` of the row the form shows |
|
|
221
|
+
| `exp-form-id` | The form's `id`, `master-form` when absent |
|
|
152
222
|
|
|
153
223
|
## `lb-unknown-page`
|
|
154
224
|
|