@loadbare/app 0.19.1 → 0.21.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 +28 -2
- package/dist/build/assemble.js.map +1 -1
- package/dist/core/lb-constants.d.ts +7 -2
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +30 -4
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/hub/lb-apply.d.ts +29 -0
- package/dist/hub/lb-apply.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +229 -32
- 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 +33 -9
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/docs/comparison.md +16 -7
- package/docs/reference/chrome.md +40 -0
- package/docs/reference/custom-elements.md +5 -4
- package/docs/reference/data-binding.md +100 -11
- package/docs/reference/names.md +12 -4
- package/docs/reference/page-files.md +2 -1
- package/docs/reference/widgets.md +10 -1
- package/docs/testing.md +5 -1
- package/package.json +1 -1
- package/skills/loadbare-app/SKILL.md +16 -6
- package/skills/loadbare-app/references/chrome.md +40 -0
- package/skills/loadbare-app/references/custom-elements.md +5 -4
- package/skills/loadbare-app/references/data-binding.md +100 -11
- package/skills/loadbare-app/references/names.md +12 -4
- package/skills/loadbare-app/references/page-files.md +2 -1
- package/skills/loadbare-app/references/widgets.md +10 -1
|
@@ -268,7 +268,7 @@ Each direction has one mechanism for each kind of message:
|
|
|
268
268
|
|
|
269
269
|
| Direction | What | How | Today |
|
|
270
270
|
|----------------|--------------------------------------------|-----------------------------|-------|
|
|
271
|
-
| 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`, `lb-request-refused` |
|
|
271
|
+
| Hub to element | State that lasts | An attribute the hub stamps | `lb-column-value`, `lb-key-value`, `lb-query-row-count`, `lb-query-unsorted-count`, `lb-query-order`, `lb-group-*`, `lb-row-*`, `lb-request-pending`, `lb-request-error`, `lb-request-refused` |
|
|
272
272
|
| Hub to element | State the platform already names | A property | A control's `value` |
|
|
273
273
|
| Hub to element | What the hub did | An optional `lb` method | `lbAttached`, `lbRowsLanded`, `lbRequestDone`, `lbDetached` |
|
|
274
274
|
| Hub to element | A moment an element started | A bubbling event | `lb-request-done` |
|
|
@@ -627,7 +627,8 @@ had there hears the event, and no custom element the hub has removed hears
|
|
|
627
627
|
### Holding rows
|
|
628
628
|
|
|
629
629
|
The hub lands every row template itself, places every row by the query's
|
|
630
|
-
order
|
|
630
|
+
order (see [Rows the user is working in](./data-binding.md#rows-the-user-is-working-in)
|
|
631
|
+
for when it does not), and builds every group the markup's group templates describe; see
|
|
631
632
|
[Order](./data-binding.md#order) and [Groups](./data-binding.md#groups). A
|
|
632
633
|
plain element carrying `lb-query` with a row template inside it needs no
|
|
633
634
|
code, so a custom element holds rows only to do something with them once
|
|
@@ -655,12 +656,12 @@ Everything else is the hub's:
|
|
|
655
656
|
|-------------|----------------------------------------------------------|
|
|
656
657
|
| Cloning | Clones the row template once per new key |
|
|
657
658
|
| Matching | Fills the live row already showing that key, when its values changed |
|
|
658
|
-
| Placing | Places every live row by the user's order or the query's |
|
|
659
|
+
| Placing | Places every live row by the user's order or the query's, and leaves them where they stand for an edit from inside the list |
|
|
659
660
|
| Filtering | Hides a row the user's filter does not pass, and a group whose rows are all hidden |
|
|
660
661
|
| Grouping | Builds a group where the order breaks, keeps it while its run goes on, and removes it with its last row |
|
|
661
662
|
| Removing | Marks the live rows the response says are gone as leaving, and removes them |
|
|
662
663
|
| Stamping | Stamps each live row with `lb-row-live`, `lb-key-value`, and what happened to it |
|
|
663
|
-
| Counting | Stamps `lb-query-row-count` with the number of live rows showing |
|
|
664
|
+
| Counting | Stamps `lb-query-row-count` with the number of live rows showing, `lb-query-unsorted-count` with the number out of order, and `lb-query-order` with the order placing them |
|
|
664
665
|
|
|
665
666
|
`lb-options.browser.ts` and `lb-table.browser.ts` in
|
|
666
667
|
[`@loadbare/widgets`](./widgets.md) are two uses of `lbRowsLanded`: one
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A page shows server data by naming queries and columns in its HTML, and asks
|
|
4
4
|
the server to change that data by naming requests. The developer writes
|
|
5
|
-
|
|
5
|
+
seventeen `lb-` attributes. The server declares every query a page may show and
|
|
6
6
|
every request it may send, and refuses anything it has not declared.
|
|
7
7
|
|
|
8
8
|
Everything is a query. A query is a name for rows, of kind `row` or `rows`,
|
|
@@ -54,6 +54,7 @@ each with its key, and permits the three requests on `roster`; see
|
|
|
54
54
|
| `lb-select` | A checkbox in a row template | Nothing: it selects its live row; see [Selecting rows](#selecting-rows) |
|
|
55
55
|
| `lb-request` | Any element | The request it sends when it commits |
|
|
56
56
|
| `lb-url-link` | An `<a>` | A link between pages; see [chrome](./chrome.md#links) |
|
|
57
|
+
| `lb-url-parm` | An `<a lb-url-link>` in a row | Columns of the row its `href` carries as parms; see [chrome](./chrome.md#a-link-from-a-row) |
|
|
57
58
|
| `lb-url-push` | An element with `lb-request` | A URL change that pushes a history entry |
|
|
58
59
|
| `lb-url-unknown` | A `<dialog>` in the chrome | The dialog for a URL that names no page |
|
|
59
60
|
|
|
@@ -66,8 +67,10 @@ builder writes a stamp, and a stylesheet or a custom element reads it.
|
|
|
66
67
|
| `lb-key-value` | The key of a live row, or of a `row` landed on an element |
|
|
67
68
|
| `lb-row-live` | The element is a live row |
|
|
68
69
|
| `lb-query-row-count` | The number of live rows an element shows |
|
|
70
|
+
| `lb-query-unsorted-count` | The number of them out of order; see [Rows the user is working in](#rows-the-user-is-working-in) |
|
|
71
|
+
| `lb-query-order` | The order placing them; see [Order](#order) |
|
|
69
72
|
| `lb-group-live`, `lb-group-column`, `lb-group-value` | A group, the column it breaks on, and its value; see [Groups](#groups) |
|
|
70
|
-
| `lb-row-created`, `lb-row-changed`, `lb-row-moved`, `lb-row-requested` | What happened to a row; see [What happened to a row](#what-happened-to-a-row) |
|
|
73
|
+
| `lb-row-created`, `lb-row-changed`, `lb-row-moved`, `lb-row-requested`, `lb-row-unsorted` | What happened to a row; see [What happened to a row](#what-happened-to-a-row) |
|
|
71
74
|
| `lb-row-leaving`, `lb-group-leaving` | A row or group on its way out |
|
|
72
75
|
| `lb-row-editing` | The row a form is pointed at; see [Editing a row in one form](#editing-a-row-in-one-form) |
|
|
73
76
|
| `lb-row-selected` | A row whose `lb-select` is ticked |
|
|
@@ -147,6 +150,10 @@ no row fills.
|
|
|
147
150
|
| Any other custom element | `lb-column-value` only |
|
|
148
151
|
| Any other element | Its text content, and `lb-column-value` |
|
|
149
152
|
|
|
153
|
+
A column lands in one attribute besides: the `href` of a link carrying
|
|
154
|
+
`lb-url-parm` that names it; see
|
|
155
|
+
[A link from a row](./chrome.md#a-link-from-a-row).
|
|
156
|
+
|
|
150
157
|
A control is an `<input>`, `<select>` or `<textarea>`, or a form-associated
|
|
151
158
|
custom element with a `value` property that fires `change`. The hub sets a
|
|
152
159
|
control's `value`, and gathers it back under the same column. A custom
|
|
@@ -218,7 +225,9 @@ places it immediately before the template:
|
|
|
218
225
|
The hub matches each row to a live row by its key. All rows decide
|
|
219
226
|
membership: a live row whose key did not arrive leaves. A patch changes only
|
|
220
227
|
the rows it names, and every other live row keeps its content. The hub
|
|
221
|
-
places
|
|
228
|
+
places live rows by the query's order, except that an edit from inside the
|
|
229
|
+
list leaves them where they stand; see [Order](#order) and
|
|
230
|
+
[Rows the user is working in](#rows-the-user-is-working-in). A row that
|
|
222
231
|
does not pass the user's filter is `hidden`; see [Filters](#filters).
|
|
223
232
|
|
|
224
233
|
A live row whose values arrive as it already shows them is not filled
|
|
@@ -290,10 +299,71 @@ numerically whatever JSON type its values arrive as, and a value that is no
|
|
|
290
299
|
value of its declared type compares as `null` does. `readAs` in
|
|
291
300
|
`@loadbare/app/types` is the rule the hub applies.
|
|
292
301
|
|
|
302
|
+
The element carrying `lb-query` carries `lb-query-order`, the order
|
|
303
|
+
placing its rows as an order's text, the user's when one is chosen and
|
|
304
|
+
the server's otherwise. Rows with no order carry none.
|
|
305
|
+
|
|
293
306
|
Rows that compare equal keep the order they arrived in, a patch's new rows
|
|
294
307
|
after the rows already showing. A row moves only when the order
|
|
295
308
|
puts it somewhere else, so all rows landing again unchanged move nothing.
|
|
296
309
|
|
|
310
|
+
### Rows the user is working in
|
|
311
|
+
|
|
312
|
+
A landing that answers a request sent from inside a list moves none of that
|
|
313
|
+
list's rows. The request is from inside the list when the list is the
|
|
314
|
+
nearest element carrying `lb-query` around the element that sent it: a
|
|
315
|
+
control in a live row, or a ghost row. A form that
|
|
316
|
+
[`--lb-edit`](#editing-a-row-in-one-form) pointed at a live row finishes an
|
|
317
|
+
edit begun in that row, so its request is from inside the row's list,
|
|
318
|
+
wherever the form sits. Any other form elsewhere on the page is not inside
|
|
319
|
+
the list. A user who changes a value sees the value change, and the row
|
|
320
|
+
stays where they were working:
|
|
321
|
+
|
|
322
|
+
| The answer | The row |
|
|
323
|
+
|------------------------------------------|---------------------------------------------------|
|
|
324
|
+
| Changes a column the order reads | Stays where it stands |
|
|
325
|
+
| Creates a row | Goes after the last row of its group, or last of all |
|
|
326
|
+
| Drops a row | Leaves |
|
|
327
|
+
| Changes a row so the filter hides it | Stays showing |
|
|
328
|
+
| Changes the column its group breaks on | Stays under its group's heading |
|
|
329
|
+
|
|
330
|
+
A patch and all rows answering the same edit land the same way. A row left
|
|
331
|
+
where the order or the filter would not leave it is stamped
|
|
332
|
+
`lb-row-unsorted`, and the element carrying `lb-query` carries
|
|
333
|
+
`lb-query-unsorted-count`, the number of such rows. Another element naming
|
|
334
|
+
the same query places its rows by the order: the user was not working
|
|
335
|
+
there.
|
|
336
|
+
|
|
337
|
+
The rows are placed by the order again, and every `lb-row-unsorted` is
|
|
338
|
+
cleared, when the user asks: when the page loads, when the user's order or
|
|
339
|
+
filter changes, or on `--lb-sort`. A button names the list with HTML's
|
|
340
|
+
`commandfor`, and a stylesheet shows it only while it has something to do:
|
|
341
|
+
|
|
342
|
+
```html
|
|
343
|
+
<div id="roster" lb-query="roster">
|
|
344
|
+
<button type="button" class="resort" commandfor="roster" command="--lb-sort">Re-sort</button>
|
|
345
|
+
<ul>
|
|
346
|
+
<template><li><input lb-column="name" lb-request="lb-row-update" /></li></template>
|
|
347
|
+
</ul>
|
|
348
|
+
</div>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
```css
|
|
352
|
+
.resort {
|
|
353
|
+
display: none;
|
|
354
|
+
}
|
|
355
|
+
[lb-query-unsorted-count]:not([lb-query-unsorted-count="0"]) .resort {
|
|
356
|
+
display: revert;
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
`--lb-sort` places the rows the hub holds, with no round trip. Aimed at an
|
|
361
|
+
element that carries no `lb-query`, or shows no rows the hub holds, it is
|
|
362
|
+
reported to the console. A custom element that reorders rows by a request of
|
|
363
|
+
its own dispatches the same command on the list once the answer lands, with
|
|
364
|
+
`new CommandEvent("command", { command: "--lb-sort" })`: the user asked for
|
|
365
|
+
the move.
|
|
366
|
+
|
|
297
367
|
### Filters
|
|
298
368
|
|
|
299
369
|
Write `lb-filter` on the element carrying `lb-query`, naming the columns of
|
|
@@ -311,7 +381,9 @@ its rows the user may filter, separated by commas. The column of
|
|
|
311
381
|
```
|
|
312
382
|
|
|
313
383
|
A row that does not pass every filter is `hidden`, and a ticked `lb-select`
|
|
314
|
-
in it is cleared. A
|
|
384
|
+
in it is cleared. A row an edit from inside the list changed stays showing
|
|
385
|
+
until the rows are placed again; see
|
|
386
|
+
[Rows the user is working in](#rows-the-user-is-working-in). A group whose rows are all hidden is hidden too
|
|
315
387
|
([miswart](../miswarts.md#rows-hidden-by-a-filter)). An empty
|
|
316
388
|
choice filters nothing.
|
|
317
389
|
|
|
@@ -393,7 +465,9 @@ Content after the nested template lands after the group's rows, which is
|
|
|
393
465
|
where a group's footer goes.
|
|
394
466
|
|
|
395
467
|
A heading is filled from its group's first row, so it may show a column
|
|
396
|
-
other than the one the group breaks on.
|
|
468
|
+
other than the one the group breaks on. A row an edit from inside the list
|
|
469
|
+
moved to another group stays under its old heading, and the heading shows
|
|
470
|
+
the row as it stood, until the rows are placed again. The hub stamps each top-level
|
|
397
471
|
element of a group with `lb-group-live`, `lb-group-column` and
|
|
398
472
|
`lb-group-value`. A row creates its group, and a group leaves with its last
|
|
399
473
|
row. When the order changes, a group whose run goes on is kept and moved,
|
|
@@ -442,6 +516,7 @@ Every change to a list is one a stylesheet can see:
|
|
|
442
516
|
| `lb-row-changed` | Its values changed when the hub last touched it |
|
|
443
517
|
| `lb-row-moved` | Its values changed, and it now stands elsewhere |
|
|
444
518
|
| `lb-row-requested` | `created`, `changed` or `moved` by this page's request |
|
|
519
|
+
| `lb-row-unsorted` | Stands where the order would not put it |
|
|
445
520
|
| `lb-row-leaving` | A row on its way out |
|
|
446
521
|
| `lb-group-leaving` | A group on its way out |
|
|
447
522
|
|
|
@@ -450,6 +525,9 @@ The hub touches a row when an answer names it. `lb-row-created`,
|
|
|
450
525
|
applied again is removed and added as two changes, so an animation keyed to
|
|
451
526
|
it plays again. `lb-row-requested` is cleared at every landing of the row's
|
|
452
527
|
query, and set only by a landing that answers a request from the page.
|
|
528
|
+
`lb-row-unsorted` is a state, not an event: it stays until the rows are
|
|
529
|
+
placed by the order; see
|
|
530
|
+
[Rows the user is working in](#rows-the-user-is-working-in).
|
|
453
531
|
|
|
454
532
|
A row or a group that leaves loses `lb-row-live` or `lb-group-live`, takes
|
|
455
533
|
`lb-row-leaving` or `lb-group-leaving` and `inert`
|
|
@@ -498,7 +576,9 @@ insert form above: it sits inside `lb-query="roster"` so its request is for
|
|
|
498
576
|
|
|
499
577
|
The hub stamps every element that holds a row template with
|
|
500
578
|
`lb-query-row-count`, the number of live rows it shows. A row a filter
|
|
501
|
-
hides is not counted.
|
|
579
|
+
hides is not counted. Beside it, `lb-query-unsorted-count` is the number of
|
|
580
|
+
rows out of order; see
|
|
581
|
+
[Rows the user is working in](#rows-the-user-is-working-in). An empty query is a stylesheet rule:
|
|
502
582
|
|
|
503
583
|
```html
|
|
504
584
|
<div lb-query="roster">
|
|
@@ -956,6 +1036,12 @@ An `lb-show` in the form reads from the row it was pointed at. With no row,
|
|
|
956
1036
|
every column is null, so `lb-show="!id"` shows only while entering a new
|
|
957
1037
|
row.
|
|
958
1038
|
|
|
1039
|
+
A request from a form Edit pointed is sent from inside the row's list, so
|
|
1040
|
+
the row stays where the user was working, even when the filter would now
|
|
1041
|
+
hide it or the order would move it; see
|
|
1042
|
+
[Rows the user is working in](#rows-the-user-is-working-in). A form New
|
|
1043
|
+
pointed is not inside any list, and its rows are placed by the order.
|
|
1044
|
+
|
|
959
1045
|
A successful request from the form lets it go, as Cancel does: the form
|
|
960
1046
|
empties, its controls return to their defaults, and the stamps go. A failed
|
|
961
1047
|
one leaves the form as the user had it, to correct.
|
|
@@ -980,8 +1066,8 @@ submits the form instead.
|
|
|
980
1066
|
|
|
981
1067
|
A command the hub cannot carry out is reported to the console: Edit from
|
|
982
1068
|
outside a live row of the form's query, Edit for a key the hub holds no row
|
|
983
|
-
for, and any
|
|
984
|
-
`lb-query`.
|
|
1069
|
+
for, and any of these three commands aimed at an element that is not a form
|
|
1070
|
+
carrying `lb-query`.
|
|
985
1071
|
|
|
986
1072
|
### Selecting rows
|
|
987
1073
|
|
|
@@ -1228,7 +1314,7 @@ The developer writes `lb-` attributes in markup, and script never assigns
|
|
|
1228
1314
|
them. The builder checks the markup of the chrome and of every page, after
|
|
1229
1315
|
expansion, and refuses to build:
|
|
1230
1316
|
|
|
1231
|
-
- an `lb-` attribute that is not one of the
|
|
1317
|
+
- an `lb-` attribute that is not one of the seventeen the developer writes;
|
|
1232
1318
|
`lb-exp-slot` and `lb-exp-template` are consumed by expansion and never
|
|
1233
1319
|
reach the check
|
|
1234
1320
|
- `lb-request` naming an `lb-` request other than the three Loadbare provides
|
|
@@ -1241,6 +1327,9 @@ expansion, and refuses to build:
|
|
|
1241
1327
|
a form's own when the form carries `lb-query`, and otherwise the nearest
|
|
1242
1328
|
`lb-query` around the element
|
|
1243
1329
|
- `lb-url-link` on anything but an `<a>`
|
|
1330
|
+
- `lb-url-parm` on anything but an `<a>` carrying `lb-url-link`, naming no
|
|
1331
|
+
column, naming columns not separated by commas or one beginning `lb-`, or
|
|
1332
|
+
with no row around it
|
|
1244
1333
|
- `lb-url-push` on an element without `lb-request`
|
|
1245
1334
|
- `lb-url-unknown` on anything but a `<dialog>`, or outside `<lb-hub>`
|
|
1246
1335
|
- `lb-show` on a `<template>`, or on a row template's root
|
|
@@ -1250,8 +1339,8 @@ expansion, and refuses to build:
|
|
|
1250
1339
|
no column
|
|
1251
1340
|
- `lb-select` on anything but `<input type="checkbox">`, outside a row
|
|
1252
1341
|
template, or beside `lb-column` or `lb-request`
|
|
1253
|
-
- a `command` beginning `--lb-` that is not one of the
|
|
1254
|
-
- one of the
|
|
1342
|
+
- a `command` beginning `--lb-` that is not one of the four commands
|
|
1343
|
+
- one of the four commands with no `commandfor`
|
|
1255
1344
|
- `lb-group` on anything but a `<template>`, or on one holding no
|
|
1256
1345
|
`<template>` for its contents
|
|
1257
1346
|
- an aggregate on a `<template>`, or any but `lb-count` naming no column
|
package/docs/reference/names.md
CHANGED
|
@@ -66,7 +66,7 @@ A widget package declares these. An application never does.
|
|
|
66
66
|
|
|
67
67
|
## Attributes
|
|
68
68
|
|
|
69
|
-
The developer writes
|
|
69
|
+
The developer writes seventeen attributes in pages and the chrome, and the
|
|
70
70
|
builder refuses any other `lb-` attribute there. `lb-exp-slot` and
|
|
71
71
|
`lb-exp-template` are written for expansion, which removes them before the
|
|
72
72
|
check. The hub and the builder write the rest, as stamps, and script never
|
|
@@ -84,6 +84,7 @@ assigns one.
|
|
|
84
84
|
| `lb-select` | Developer | [Selecting rows](./data-binding.md#selecting-rows) |
|
|
85
85
|
| `lb-request` | Developer | [Requests](./data-binding.md#requests) |
|
|
86
86
|
| `lb-url-link` | Developer | [Links](./chrome.md#links) |
|
|
87
|
+
| `lb-url-parm` | Developer | [A link from a row](./chrome.md#a-link-from-a-row) |
|
|
87
88
|
| `lb-url-push` | Developer | [Query parms](./chrome.md#query-parms) |
|
|
88
89
|
| `lb-url-unknown` | Developer | [An unknown page](./chrome.md#an-unknown-page) |
|
|
89
90
|
| `lb-exp-slot` | Developer, consumed by expansion | [The slot](./custom-elements.md#the-slot) |
|
|
@@ -92,6 +93,8 @@ assigns one.
|
|
|
92
93
|
| `lb-key-value` | Hub | [Landing](./data-binding.md#landing), [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form) |
|
|
93
94
|
| `lb-row-live` | Hub | [Landing](./data-binding.md#landing) |
|
|
94
95
|
| `lb-query-row-count` | Hub | [Counting rows](./data-binding.md#counting-rows) |
|
|
96
|
+
| `lb-query-unsorted-count`, `lb-row-unsorted` | Hub | [Rows the user is working in](./data-binding.md#rows-the-user-is-working-in) |
|
|
97
|
+
| `lb-query-order` | Hub | [Order](./data-binding.md#order) |
|
|
95
98
|
| `lb-group-live`, `lb-group-column`, `lb-group-value` | Hub | [Groups](./data-binding.md#groups) |
|
|
96
99
|
| `lb-row-created`, `lb-row-changed`, `lb-row-moved`, `lb-row-requested` | Hub | [What happened to a row](./data-binding.md#what-happened-to-a-row) |
|
|
97
100
|
| `lb-row-leaving`, `lb-group-leaving` | Hub | [What happened to a row](./data-binding.md#what-happened-to-a-row) |
|
|
@@ -135,6 +138,7 @@ Loadbare/app owns every value of HTML's `command` attribute beginning with
|
|
|
135
138
|
| `--lb-edit` | [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form) |
|
|
136
139
|
| `--lb-new` | [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form) |
|
|
137
140
|
| `--lb-release` | [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form) |
|
|
141
|
+
| `--lb-sort` | [Rows the user is working in](./data-binding.md#rows-the-user-is-working-in) |
|
|
138
142
|
|
|
139
143
|
## Reserved tags
|
|
140
144
|
|
|
@@ -191,6 +195,8 @@ imports them rather than writing a string.
|
|
|
191
195
|
| `ATTR_ROW_LIVE` | `lb-row-live` |
|
|
192
196
|
| `LIVE_ROW` | `[lb-row-live]`, the selector for a live row |
|
|
193
197
|
| `ATTR_QUERY_ROW_COUNT` | `lb-query-row-count` |
|
|
198
|
+
| `ATTR_QUERY_UNSORTED_COUNT` | `lb-query-unsorted-count` |
|
|
199
|
+
| `ATTR_QUERY_ORDER` | `lb-query-order` |
|
|
194
200
|
| `ATTR_GROUP` | `lb-group` |
|
|
195
201
|
| `ATTR_GROUP_LIVE` | `lb-group-live` |
|
|
196
202
|
| `ATTR_GROUP_COLUMN` | `lb-group-column` |
|
|
@@ -209,6 +215,7 @@ imports them rather than writing a string.
|
|
|
209
215
|
| `ATTR_ROW_MOVED` | `lb-row-moved` |
|
|
210
216
|
| `ATTR_ROW_REQUESTED` | `lb-row-requested` |
|
|
211
217
|
| `REQUESTED_CREATED`, `REQUESTED_CHANGED`, `REQUESTED_MOVED` | `created`, `changed`, `moved` |
|
|
218
|
+
| `ATTR_ROW_UNSORTED` | `lb-row-unsorted` |
|
|
212
219
|
| `ATTR_ROW_LEAVING` | `lb-row-leaving` |
|
|
213
220
|
| `ATTR_GROUP_LEAVING` | `lb-group-leaving` |
|
|
214
221
|
| `ATTR_REQUEST` | `lb-request` |
|
|
@@ -218,8 +225,8 @@ imports them rather than writing a string.
|
|
|
218
225
|
| `ATTR_REQUEST_ERROR` | `lb-request-error` |
|
|
219
226
|
| `ATTR_REQUEST_REFUSED` | `lb-request-refused` |
|
|
220
227
|
| `LB_REFUSAL_STATUS` | `422` |
|
|
221
|
-
| `COMMAND_EDIT`, `COMMAND_NEW`, `COMMAND_RELEASE` | `--lb-edit`, `--lb-new`, `--lb-release` |
|
|
222
|
-
| `LB_COMMANDS` | All
|
|
228
|
+
| `COMMAND_EDIT`, `COMMAND_NEW`, `COMMAND_RELEASE`, `COMMAND_SORT` | `--lb-edit`, `--lb-new`, `--lb-release`, `--lb-sort` |
|
|
229
|
+
| `LB_COMMANDS` | All four commands |
|
|
223
230
|
| `LB_COMMAND_PREFIX` | `--lb-` |
|
|
224
231
|
| `ATTR_ROW_EDITING` | `lb-row-editing` |
|
|
225
232
|
| `ATTR_SELECT` | `lb-select` |
|
|
@@ -238,13 +245,14 @@ imports them rather than writing a string.
|
|
|
238
245
|
| `URL_COLUMN_PAGE_LABEL` | `lb-page-label` |
|
|
239
246
|
| `URL_COLUMN_PAGE_UNKNOWN` | `lb-page-unknown` |
|
|
240
247
|
| `ATTR_URL_LINK` | `lb-url-link` |
|
|
248
|
+
| `ATTR_URL_PARM` | `lb-url-parm` |
|
|
241
249
|
| `ATTR_URL_PUSH` | `lb-url-push` |
|
|
242
250
|
| `ATTR_URL_UNKNOWN` | `lb-url-unknown` |
|
|
243
251
|
| `ATTR_EXP_SLOT` | `lb-exp-slot` |
|
|
244
252
|
| `ATTR_EXP_TEMPLATE` | `lb-exp-template` |
|
|
245
253
|
| `ATTR_PAGE` | `lb-page` |
|
|
246
254
|
| `ATTR_PAGE_TITLE` | `lb-page-title` |
|
|
247
|
-
| `DEVELOPER_ATTRIBUTES` | The
|
|
255
|
+
| `DEVELOPER_ATTRIBUTES` | The seventeen attributes a developer writes |
|
|
248
256
|
| `HUB_TAG_NAME` | `lb-hub` |
|
|
249
257
|
| `LB_ENDPOINT` | `/lb` |
|
|
250
258
|
| `LB_REQUEST_TIMEOUT_MS` | `10000` |
|
|
@@ -382,7 +382,8 @@ one row dropped, one row edited — and leave `refresh` empty. A refreshed
|
|
|
382
382
|
A change that seems to need a refresh usually has a patch:
|
|
383
383
|
|
|
384
384
|
- A row whose position changes: the hub places it by the query's
|
|
385
|
-
[order](./data-binding.md#order)
|
|
385
|
+
[order](./data-binding.md#order), or leaves it where the user is working
|
|
386
|
+
when the request came from inside its list; a refresh would do the same.
|
|
386
387
|
- A group that appears or goes: the hub makes a group with its first row
|
|
387
388
|
and removes it with its last, so no row stands in for an empty one.
|
|
388
389
|
- A row whose other columns change with the edit: re-read the row and patch
|
|
@@ -155,7 +155,9 @@ row, the row template, and optionally a footer, each as a `<template>`:
|
|
|
155
155
|
| `<template lb-exp-template="foot">` | The `<tfoot>` |
|
|
156
156
|
| Any other `<template>` | The row or group template, in the `<tbody>` |
|
|
157
157
|
|
|
158
|
-
- The hub places the rows by the query's order and builds its groups
|
|
158
|
+
- The hub places the rows by the query's order and builds its groups, and
|
|
159
|
+
leaves them where they stand for an edit from inside the table; see
|
|
160
|
+
[Rows the user is working in](./data-binding.md#rows-the-user-is-working-in). The
|
|
159
161
|
rows land in the one `<tbody>`, so a group here is a heading row with its
|
|
160
162
|
rows after it.
|
|
161
163
|
- `lb-order` and `lb-filter` go on the `lb-table` itself, beside
|
|
@@ -174,6 +176,13 @@ row, the row template, and optionally a footer, each as a `<template>`:
|
|
|
174
176
|
- Text selected in a cell whose `lb-column` the table's `lb-filter` names
|
|
175
177
|
becomes that column's filter in `lb-choices`: `=` for the whole text,
|
|
176
178
|
`^=` from its start, `$=` up to its end, `*=` otherwise.
|
|
179
|
+
- The heading of the order's leading column carries a triangle for the
|
|
180
|
+
direction, read from [`lb-query-order`](./data-binding.md#order). A
|
|
181
|
+
heading's column is the `lb-column` in the cell at its position in the row
|
|
182
|
+
template. While rows stand out of order the triangle carries
|
|
183
|
+
`data-unsorted` and a click on its heading re-sorts. With `lb-order`, a
|
|
184
|
+
click on the sorted heading reverses the order and a click on another
|
|
185
|
+
sorts by its column. Not on a grouped table.
|
|
177
186
|
|
|
178
187
|
## `lb-confirm`
|
|
179
188
|
|
package/docs/testing.md
CHANGED
|
@@ -208,7 +208,9 @@ evidence here.
|
|
|
208
208
|
- `lb-query-row-count` counts the rows showing, so all rows and a patch
|
|
209
209
|
ending in the same state report the same number, and a row a filter hides
|
|
210
210
|
is not counted
|
|
211
|
-
- the order places all rows and a patch alike,
|
|
211
|
+
- the order places all rows and a patch alike, except where an edit came
|
|
212
|
+
from inside the list, which leaves its rows standing and stamped until
|
|
213
|
+
the user asks for the order; groups come and go with
|
|
212
214
|
their rows to any depth, aggregates follow every landing, and every change
|
|
213
215
|
leaves a stamp a stylesheet can see (`lb-order.test.ts`)
|
|
214
216
|
- a filter's text reads and passes values as documented, and a choice of
|
|
@@ -279,6 +281,8 @@ What the hub is tested for here:
|
|
|
279
281
|
`lb-page-label`, and a column per query parm, and sets the document title
|
|
280
282
|
- `lb-url-link` pushes state and swaps the page on a plain primary click,
|
|
281
283
|
`popstate` reverses it, and an ordinary anchor is left alone
|
|
284
|
+
- `lb-url-parm` writes a link's `href` from its row as held, starting from
|
|
285
|
+
the `href` as written every time (`lb-apply.test.ts`)
|
|
282
286
|
- a control inside `lb-query="lb-url"` writes its parm, replacing the history
|
|
283
287
|
entry or pushing one with `lb-url-push`, and the page's queries reload
|
|
284
288
|
- an `lb-url` item in a server answer writes the URL and lands the page
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: loadbare-app
|
|
3
|
-
description: Build server-bound web applications with Loadbare/app. Covers the file conventions the builder finds by name (`chrome.html`, `*.page.html`, `*.queries.ts`, `*.requests.ts`, `imports.ts`, `<tag>.html`, `<tag>.browser.ts`); the `lb-*` attribute vocabulary that lands query rows on HTML and issues requests (`lb-query`, `lb-column`, `lb-show`, `lb-request`); queries declared with `row(key, run)` and `rows(key, run)`; the URL as the hub's own query `lb-url`, with `lb-url-link`, `lb-url-push` and `lb-url-unknown`; the user's order and filters as the hub's query `lb-choices`, read by `lb-order` and `lb-filter`; one form pointed at a row by the `--lb-edit`, `--lb-new` and `--lb-release` commands; build-time expansion with `exp-*` parameters, `lb-exp-slot` and `lb-exp-template`; custom elements as form-associated controls and row hosts; the Express wiring with `hubRoutes`; and the `@loadbare/widgets` library. Use whenever a task involves `@loadbare/app`, `@loadbare/widgets`, `loadbare-app-build`, an `lb-` attribute, or a page, query, request or custom element file in a Loadbare application. The model is not React, htmx or REST, and cannot be inferred from them.
|
|
3
|
+
description: Build server-bound web applications with Loadbare/app. Covers the file conventions the builder finds by name (`chrome.html`, `*.page.html`, `*.queries.ts`, `*.requests.ts`, `imports.ts`, `<tag>.html`, `<tag>.browser.ts`); the `lb-*` attribute vocabulary that lands query rows on HTML and issues requests (`lb-query`, `lb-column`, `lb-show`, `lb-request`); queries declared with `row(key, run)` and `rows(key, run)`; the URL as the hub's own query `lb-url`, with `lb-url-link`, `lb-url-parm`, `lb-url-push` and `lb-url-unknown`; the user's order and filters as the hub's query `lb-choices`, read by `lb-order` and `lb-filter`; one form pointed at a row by the `--lb-edit`, `--lb-new` and `--lb-release` commands; re-sorting a list with `--lb-sort`; build-time expansion with `exp-*` parameters, `lb-exp-slot` and `lb-exp-template`; custom elements as form-associated controls and row hosts; the Express wiring with `hubRoutes`; and the `@loadbare/widgets` library. Use whenever a task involves `@loadbare/app`, `@loadbare/widgets`, `loadbare-app-build`, an `lb-` attribute, or a page, query, request or custom element file in a Loadbare application. The model is not React, htmx or REST, and cannot be inferred from them.
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
metadata:
|
|
6
6
|
package: "@loadbare/app"
|
|
@@ -191,6 +191,12 @@ row is filled from the nested query's last answer, whatever order they land
|
|
|
191
191
|
in.
|
|
192
192
|
|
|
193
193
|
**A `rows` query declares its order, and the hub places every row by it.**
|
|
194
|
+
An edit sent from inside a list, or from a form `--lb-edit` pointed at one
|
|
195
|
+
of its rows, leaves that list's rows where they stand, stamped `lb-row-unsorted` where out of order, until the page loads, the
|
|
196
|
+
user's order or filter changes, or a button with `commandfor` naming the
|
|
197
|
+
list sends `command="--lb-sort"`, which places them with no round trip;
|
|
198
|
+
show it by `[lb-query-unsorted-count]`. Never refresh to make rows hold
|
|
199
|
+
still, and never to put them back in order.
|
|
194
200
|
`rows("id", run, { order: "category_order,name" })`; a column after `-` sorts
|
|
195
201
|
descending, and values compare by JSON type, so a numeric sort column is a
|
|
196
202
|
JSON number or is declared one: `types: { amount: "number" }` beside
|
|
@@ -265,7 +271,8 @@ in every row. Write one form naming the set's query, outside every row,
|
|
|
265
271
|
often in a `<dialog>`, and give it an `id`. A `type="button"` with
|
|
266
272
|
`commandfor="<id>"` and `command="--lb-edit"` in a live row fills it from
|
|
267
273
|
that row with no round trip; `--lb-new` starts it empty for an insert;
|
|
268
|
-
`--lb-release` lets it go.
|
|
274
|
+
`--lb-release` lets it go. (`--lb-sort` is the fourth command, for a list,
|
|
275
|
+
not a form.) The form's `lb-key-value` is the row's key, empty
|
|
269
276
|
for a new row, absent when not in use, and a stylesheet shows Save or Save
|
|
270
277
|
new by it. A successful request from the form, or its dialog closing, lets
|
|
271
278
|
it go. Which row is being edited is never a query parm. A row that must be
|
|
@@ -321,7 +328,8 @@ picker in a row the request adds: its answer did not change, and the hub
|
|
|
321
328
|
fills a new row from the last one.
|
|
322
329
|
|
|
323
330
|
**The usual reasons for a refresh each have a patch.**
|
|
324
|
-
- A row whose position changes: the hub places it by the query's order
|
|
331
|
+
- A row whose position changes: the hub places it by the query's order, or
|
|
332
|
+
holds it where the user is working; a refresh changes neither.
|
|
325
333
|
- A group that appears or goes: the hub makes it with its first row and
|
|
326
334
|
removes it with its last.
|
|
327
335
|
- A row whose other columns change with the edit: re-read the row and patch
|
|
@@ -359,7 +367,9 @@ per query parm. A control inside `lb-query="lb-url"` carrying
|
|
|
359
367
|
`lb-request="lb-row-update"` writes its parm; the hub replaces the history
|
|
360
368
|
entry, or pushes one when the control carries `lb-url-push`, and reloads the
|
|
361
369
|
page's queries with no request to the server. An `<a lb-url-link>` moves
|
|
362
|
-
to its `href
|
|
370
|
+
to its `href`; inside a row, `lb-url-parm="topic_id"` adds that column of
|
|
371
|
+
the row to the `href` as the parm of the same name, so a link to another
|
|
372
|
+
page narrowed by the row is a link, never a request or script. Queries still take no arguments: `contextFor(req, parms)`
|
|
363
373
|
puts parms onto `ctx`, and a query reads them there. Read them from
|
|
364
374
|
`parms`, never `req.query`, because `contextFor` may be called twice for one
|
|
365
375
|
request. A parm is user input, so validate it where it is read. Do not
|
|
@@ -393,10 +403,10 @@ whole data channel.
|
|
|
393
403
|
|
|
394
404
|
**The developer writes `lb-*` attributes in markup, and script never
|
|
395
405
|
assigns them.** The builder refuses any `lb-` attribute other than the
|
|
396
|
-
|
|
406
|
+
seventeen in [Attributes](references/names.md#attributes): `lb-query`,
|
|
397
407
|
`lb-column`, `lb-show`, `lb-order`, `lb-filter`, `lb-group`, `lb-count`,
|
|
398
408
|
`lb-sum`, `lb-avg`, `lb-min`, `lb-max`, `lb-select`, `lb-request`,
|
|
399
|
-
`lb-url-link`, `lb-url-push` and `lb-url-unknown`. `lb-exp-slot` and
|
|
409
|
+
`lb-url-link`, `lb-url-parm`, `lb-url-push` and `lb-url-unknown`. `lb-exp-slot` and
|
|
400
410
|
`lb-exp-template` are expansion's, and never reach the page. Everything
|
|
401
411
|
else with the prefix is a stamp the hub or the builder writes.
|
|
402
412
|
|
|
@@ -60,6 +60,7 @@ Everything else is optional:
|
|
|
60
60
|
|-------------------------------------------|---------------------------------------------|
|
|
61
61
|
| `<link rel="stylesheet" href="/app.css">` | The bundled stylesheet |
|
|
62
62
|
| `<a lb-url-link>` | A link between pages |
|
|
63
|
+
| `<a lb-url-link lb-url-parm>` | A link carrying columns of its row |
|
|
63
64
|
| `lb-query="lb-url"` | Where the page is — see below |
|
|
64
65
|
| `<dialog lb-url-unknown>` | A message when a URL matches no page |
|
|
65
66
|
| Custom elements | The chrome, decomposed into element files |
|
|
@@ -157,6 +158,45 @@ Path space is flat: `/members` shows `members.page.html` wherever under
|
|
|
157
158
|
`/transactions?date_begin=2026-09-01` opens the page narrowed to those
|
|
158
159
|
dates.
|
|
159
160
|
|
|
161
|
+
### A link from a row
|
|
162
|
+
|
|
163
|
+
Write `lb-url-parm` on an `<a lb-url-link>` inside a row to carry columns
|
|
164
|
+
of that row to the page the link names. It names columns, separated by
|
|
165
|
+
commas, and the hub adds each to the link's query string as the parm of the
|
|
166
|
+
same name:
|
|
167
|
+
|
|
168
|
+
```html
|
|
169
|
+
<table lb-query="topics">
|
|
170
|
+
<template>
|
|
171
|
+
<tr>
|
|
172
|
+
<td lb-column="title"></td>
|
|
173
|
+
<td><a href="/events" lb-url-link lb-url-parm="topic_id" lb-column="times_presented"></a></td>
|
|
174
|
+
</tr>
|
|
175
|
+
</template>
|
|
176
|
+
</table>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
In topic 5's row the link is `<a href="/events?topic_id=5">`. The `href` is
|
|
180
|
+
written when the row lands and rewritten when it changes, so hovering,
|
|
181
|
+
copying, a middle click and a plain click all go to the same place.
|
|
182
|
+
|
|
183
|
+
- The parm is the column. Where the names differ, the row's query renames
|
|
184
|
+
the column in its SQL: `select id as topic_id`.
|
|
185
|
+
- The hub reads the row it holds, so a column no element shows is carried
|
|
186
|
+
as well as one that is.
|
|
187
|
+
- The `href` as written is the base. Its path, its parms and its fragment
|
|
188
|
+
are kept, and a named column replaces a parm of the same name.
|
|
189
|
+
- A null, empty or missing column leaves its parm off, as an empty value
|
|
190
|
+
takes a parm out of the URL. A string is written as it is, a number or a
|
|
191
|
+
boolean as JSON writes it, and any other value is left off and reported
|
|
192
|
+
on the console, as is a named column the row does not have.
|
|
193
|
+
- The row is the nearest around the link: a live row, or an element a `row`
|
|
194
|
+
landed on.
|
|
195
|
+
|
|
196
|
+
`lb-url-parm` goes only on a link carrying `lb-url-link`, since the parms it
|
|
197
|
+
writes are the application's own; see
|
|
198
|
+
[The markup checks](./data-binding.md#the-markup-checks).
|
|
199
|
+
|
|
160
200
|
### Query parms
|
|
161
201
|
|
|
162
202
|
A query parm is a column of `lb-url`. A control inside `lb-query="lb-url"`
|
|
@@ -268,7 +268,7 @@ Each direction has one mechanism for each kind of message:
|
|
|
268
268
|
|
|
269
269
|
| Direction | What | How | Today |
|
|
270
270
|
|----------------|--------------------------------------------|-----------------------------|-------|
|
|
271
|
-
| 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`, `lb-request-refused` |
|
|
271
|
+
| Hub to element | State that lasts | An attribute the hub stamps | `lb-column-value`, `lb-key-value`, `lb-query-row-count`, `lb-query-unsorted-count`, `lb-query-order`, `lb-group-*`, `lb-row-*`, `lb-request-pending`, `lb-request-error`, `lb-request-refused` |
|
|
272
272
|
| Hub to element | State the platform already names | A property | A control's `value` |
|
|
273
273
|
| Hub to element | What the hub did | An optional `lb` method | `lbAttached`, `lbRowsLanded`, `lbRequestDone`, `lbDetached` |
|
|
274
274
|
| Hub to element | A moment an element started | A bubbling event | `lb-request-done` |
|
|
@@ -627,7 +627,8 @@ had there hears the event, and no custom element the hub has removed hears
|
|
|
627
627
|
### Holding rows
|
|
628
628
|
|
|
629
629
|
The hub lands every row template itself, places every row by the query's
|
|
630
|
-
order
|
|
630
|
+
order (see [Rows the user is working in](./data-binding.md#rows-the-user-is-working-in)
|
|
631
|
+
for when it does not), and builds every group the markup's group templates describe; see
|
|
631
632
|
[Order](./data-binding.md#order) and [Groups](./data-binding.md#groups). A
|
|
632
633
|
plain element carrying `lb-query` with a row template inside it needs no
|
|
633
634
|
code, so a custom element holds rows only to do something with them once
|
|
@@ -655,12 +656,12 @@ Everything else is the hub's:
|
|
|
655
656
|
|-------------|----------------------------------------------------------|
|
|
656
657
|
| Cloning | Clones the row template once per new key |
|
|
657
658
|
| Matching | Fills the live row already showing that key, when its values changed |
|
|
658
|
-
| Placing | Places every live row by the user's order or the query's |
|
|
659
|
+
| Placing | Places every live row by the user's order or the query's, and leaves them where they stand for an edit from inside the list |
|
|
659
660
|
| Filtering | Hides a row the user's filter does not pass, and a group whose rows are all hidden |
|
|
660
661
|
| Grouping | Builds a group where the order breaks, keeps it while its run goes on, and removes it with its last row |
|
|
661
662
|
| Removing | Marks the live rows the response says are gone as leaving, and removes them |
|
|
662
663
|
| Stamping | Stamps each live row with `lb-row-live`, `lb-key-value`, and what happened to it |
|
|
663
|
-
| Counting | Stamps `lb-query-row-count` with the number of live rows showing |
|
|
664
|
+
| Counting | Stamps `lb-query-row-count` with the number of live rows showing, `lb-query-unsorted-count` with the number out of order, and `lb-query-order` with the order placing them |
|
|
664
665
|
|
|
665
666
|
`lb-options.browser.ts` and `lb-table.browser.ts` in
|
|
666
667
|
[`@loadbare/widgets`](./widgets.md) are two uses of `lbRowsLanded`: one
|