@loadbare/widgets 0.10.1 → 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.
@@ -0,0 +1,77 @@
1
+ # `lb-input`
2
+
3
+ > Status: a barebones starter. Iterative use will drive improvements.
4
+
5
+ A control wrapping an HTML `<input>`. The hub sets it from a column and
6
+ gathers it back under the same column, as it does a native `<input>`.
7
+
8
+ Requires attributes `lb-column` and `exp-label`.
9
+
10
+ ```html
11
+ <div lb-query="people">
12
+ <template>
13
+ <div>
14
+ <lb-input lb-column="name" exp-label="Name" lb-request="lb-row-update"></lb-input>
15
+ <lb-input lb-column="email" exp-label="Email" exp-readonly></lb-input>
16
+ </div>
17
+ </template>
18
+ </div>
19
+ ```
20
+
21
+ ## Expansion Attributes
22
+
23
+ These are the parameters that control build-time expansion of the final HTML.
24
+
25
+ | Parameter | Fills |
26
+ | -------------- | -------------------------------- |
27
+ | `exp-label` | the visible `<label>` text |
28
+ | `exp-type` | the input's `type`, `text` when absent |
29
+ | `exp-readonly` | the input's `readonly` attribute |
30
+
31
+ Any value on `exp-readonly` makes the input readonly. Leaving the parameter
32
+ off drops the attribute.
33
+
34
+ ## Attributes
35
+
36
+ | Attribute | Names |
37
+ | ------------ | ----------------------------------------- |
38
+ | `lb-column` | the column the input shows and gathers to |
39
+ | `lb-request` | the request a change issues |
40
+
41
+ ## The control
42
+
43
+ `lb-input` is a form-associated custom element. Its `value` property gets and
44
+ sets the value of the `<input>` inside it, and it fires `change` on itself when
45
+ that `<input>` fires `change`. A form reset returns the `<input>` to its
46
+ default. A refusal's message for its column goes to the `<input>`, as HTML's
47
+ own validity.
48
+
49
+ ## Inside a form
50
+
51
+ An `lb-input` inside an `lb-row-insert` or `lb-row-update` form carries no
52
+ `lb-request`. The hub gathers every `lb-column` whose form owner is the form
53
+ on submit and sends one request for all of them, so a widget that also sent
54
+ its own would write the same edit twice.
55
+
56
+ ```html
57
+ <form lb-query="people" lb-request="lb-row-insert">
58
+ <lb-input lb-column="name" exp-label="Name"></lb-input>
59
+ <lb-input lb-column="email" exp-label="Email"></lb-input>
60
+ <button type="submit">Add</button>
61
+ </form>
62
+ ```
63
+
64
+ ## Editing one column
65
+
66
+ With `lb-request`, the `lb-input` commits on `change`. The hub gathers its
67
+ value alone, so `lb-request="lb-row-update"` sends an `lb-row-update` for the
68
+ query and key of the row around it, with `values` holding that one column.
69
+ Any other request name sends that request with the same `query`, `key` and
70
+ `values`.
71
+
72
+ Inside `lb-query="lb-url"`, `lb-request="lb-row-update"` writes the column as a
73
+ query parm, and the hub answers with no round trip.
74
+
75
+ While the request is in flight the hub marks the `lb-input` with
76
+ `lb-request-pending`, and on failure with `lb-request-error`. Both are there
77
+ for a stylesheet to read.
@@ -0,0 +1,73 @@
1
+ # `lb-insert-dialog`
2
+
3
+ > Status: a barebones starter. Iterative use will drive improvements.
4
+
5
+ A row entered in a modal dialog, for a set being chosen from elsewhere on the
6
+ page, such as creating an account while a picker chooses one. The page
7
+ writes the controls inside the tag; the dialog supplies the form, Cancel and
8
+ Save.
9
+
10
+ Requires `exp-id`, `exp-title` and `exp-query`.
11
+
12
+ ```html
13
+ <lb-options lb-query="accounts" lb-column="account_id" exp-label="Account">
14
+ <template><option lb-column="name"></option></template>
15
+ </lb-options>
16
+ <button type="button" commandfor="new-account" command="show-modal">New</button>
17
+
18
+ <lb-insert-dialog exp-id="new-account" exp-title="New account" exp-query="accounts">
19
+ <lb-input lb-column="name" exp-label="Name"></lb-input>
20
+ </lb-insert-dialog>
21
+ ```
22
+
23
+ ## Expansion Attributes
24
+
25
+ | Parameter | Fills |
26
+ | ----------- | -------------------------------------------- |
27
+ | `exp-id` | the dialog's `id`, which buttons open |
28
+ | `exp-title` | the dialog's heading |
29
+ | `exp-query` | the `lb-query` of the form, which it inserts into |
30
+ | `exp-save` | the Save button's text, `Save` when absent |
31
+
32
+ ## Where it goes
33
+
34
+ Write it once, outside every row and every form, and open it with HTML's own
35
+ `commandfor` and `command="show-modal"` from as many buttons as need it. A
36
+ form inside another form is dropped by the parser, and `lb-table` joins every
37
+ control in a ghost row to that row's form, so the dialog cannot sit beside
38
+ the control it serves.
39
+
40
+ ## What it does
41
+
42
+ Save is the form's `lb-row-insert`. When it succeeds, the widget chooses the new row in the nearest `lb-options` around
43
+ the button that opened the dialog, fires `change` on it, and closes the
44
+ dialog. The new key comes from the patch the insert answers with, so the
45
+ handler answers with the row it created. A picker that saves its own column
46
+ saves it; one in a ghost row or a new record holds it until Save.
47
+
48
+ A refused insert leaves the dialog open to correct. Cancel and Escape close
49
+ it, and closing resets the form.
50
+
51
+ ## Opening beside the button
52
+
53
+ While the dialog is open, the button that opened it carries
54
+ `insert-dialog-opener` and the widget carries `anchored`, for a stylesheet to
55
+ place the dialog beside the button with CSS anchor positioning:
56
+
57
+ ```css
58
+ [insert-dialog-opener] {
59
+ anchor-name: --insert-dialog-opener;
60
+ }
61
+
62
+ lb-insert-dialog[anchored] .lb-insert-dialog {
63
+ position-anchor: --insert-dialog-opener;
64
+ inset: auto;
65
+ margin: 0;
66
+ position-area: block-end span-inline-end;
67
+ position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
68
+ }
69
+ ```
70
+
71
+ Only one modal is open at a time, so one anchor name serves every dialog.
72
+ Without such a rule, or opened with no button, the dialog stays where the
73
+ browser puts a modal.
@@ -0,0 +1,29 @@
1
+ # `lb-mailto`
2
+
3
+ > Status: a barebones starter. Iterative use will drive improvements.
4
+
5
+ An email address shown as written, as a `mailto:` link. Not a control:
6
+ write `lb-column` on the tag, and the hub lands the column on it and never
7
+ gathers it.
8
+
9
+ ```html
10
+ <lb-mailto lb-column="email"></lb-mailto>
11
+ ```
12
+
13
+ It takes no parameters. To edit the address, use
14
+ `<lb-input exp-type="email">`.
15
+
16
+ ## The value
17
+
18
+ The link's text is the value as it arrived. Its `href` is `mailto:` and the
19
+ address, encoded, so a value carrying `?` or `&` cannot add a subject, a body
20
+ or another recipient to the message.
21
+
22
+ A value with no `@` shows as it arrived, with no `href`. Null shows
23
+ nothing.
24
+
25
+ ## Styling
26
+
27
+ The definition is an `<a>`, with no `href` while there is no address, so
28
+ `lb-mailto a:not([href])` selects a value that is no link. The hub stamps
29
+ the tag with `lb-column-value`, the value as it arrived.
@@ -0,0 +1,65 @@
1
+ # `lb-master`
2
+
3
+ > Status: a barebones starter. Iterative use will drive improvements.
4
+
5
+ A set on one side, one of its rows on the other, and the buttons that act on
6
+ the set. A definition only, with no script of its own: it is built from
7
+ [`lb-form`](./lb-form.md) and [`lb-confirm`](./lb-confirm.md).
8
+
9
+ Requires `exp-row`.
10
+
11
+ ```html
12
+ <lb-master exp-row="account">
13
+ <template lb-exp-template="picker">
14
+ <div lb-query="lb-url">
15
+ <lb-picker lb-query="accounts" lb-column="acct" lb-request="lb-row-update"
16
+ exp-label="Account" exp-column="name"></lb-picker>
17
+ </div>
18
+ </template>
19
+ <lb-input lb-column="name" exp-label="Name" lb-request="lb-row-update"></lb-input>
20
+ <template lb-exp-template="delete-message">
21
+ Delete <b lb-column="name"></b>?
22
+ </template>
23
+ </lb-master>
24
+ ```
25
+
26
+ ## Expansion Attributes
27
+
28
+ | Parameter | Fills |
29
+ | -------------- | ---------------------------------------------- |
30
+ | `exp-row` | the `lb-query` of the row the form shows |
31
+ | `exp-form-id` | the form's `id`, `master-form` when absent |
32
+
33
+ | Template | Fills |
34
+ | ------------------------------------------- | ----------------------------- |
35
+ | `<template lb-exp-template="picker">` | the side that chooses the row |
36
+ | `<template lb-exp-template="delete-message">` | the question Delete asks |
37
+
38
+ ## The buttons
39
+
40
+ | Button | Shows | Does |
41
+ | -------- | ----------------- | --------------------------------------------- |
42
+ | New | A row on record | Sends `new`, a request the page declares, and pushes a history entry |
43
+ | Copy | A row on record | Sends `copy`, a request the page declares |
44
+ | Delete | A row on record | Asks, then sends `lb-row-delete` |
45
+ | Save new | A new row | Submits the form as `lb-row-insert`, and pushes a history entry |
46
+ | Cancel | A new row | Resets the form |
47
+
48
+ Each carries `data-mode`, `on-record` or `new`, and the stylesheet shows each
49
+ only in its mode. A new row is one whose key is empty, a row not yet entered
50
+ (see that section in the data-binding reference of the loadbare-app skill).
51
+
52
+ Which row shows is a query parm, and only the page knows its name, so New is
53
+ a request the page declares. Its handler empties the parm, and the row
54
+ query answers a row with an empty key:
55
+
56
+ ```ts
57
+ handlers: {
58
+ new: { run: async () => url({ acct: "" }), refresh: [] },
59
+ },
60
+ ```
61
+
62
+ Choosing the picker's blank does the same.
63
+
64
+ Copy goes to the server rather than filling the form, because a copy is a new
65
+ row in the set, and only the server can bring its children along.
@@ -0,0 +1,53 @@
1
+ # `lb-number`
2
+
3
+ > Status: a barebones starter. Iterative use will drive improvements.
4
+
5
+ A number shown by the browser's `Intl.NumberFormat`. Not a control: write
6
+ `lb-column` on the tag, and the hub lands the column on it and never gathers
7
+ it.
8
+
9
+ ```html
10
+ <lb-number lb-column="balance" exp-style="currency" exp-currency="USD"></lb-number>
11
+ ```
12
+
13
+ ## Expansion Attributes
14
+
15
+ Each parameter is one of `Intl.NumberFormat`'s options, in kebab-case. A
16
+ parameter not given leaves Intl's default.
17
+
18
+ | Parameter | `Intl.NumberFormat` option |
19
+ | -------------------------------- | -------------------------------------- |
20
+ | `exp-locale` | the locale, the browser's when absent |
21
+ | `exp-style` | `style` |
22
+ | `exp-currency` | `currency` |
23
+ | `exp-currency-display` | `currencyDisplay` |
24
+ | `exp-currency-sign` | `currencySign` |
25
+ | `exp-unit` | `unit` |
26
+ | `exp-unit-display` | `unitDisplay` |
27
+ | `exp-notation` | `notation` |
28
+ | `exp-compact-display` | `compactDisplay` |
29
+ | `exp-sign-display` | `signDisplay` |
30
+ | `exp-minimum-integer-digits` | `minimumIntegerDigits` |
31
+ | `exp-minimum-fraction-digits` | `minimumFractionDigits` |
32
+ | `exp-maximum-fraction-digits` | `maximumFractionDigits` |
33
+ | `exp-minimum-significant-digits` | `minimumSignificantDigits` |
34
+ | `exp-maximum-significant-digits` | `maximumSignificantDigits` |
35
+
36
+ ## The value
37
+
38
+ The widget formats the value as the string it arrived as, so a decimal the
39
+ query sends as a string keeps every digit. A value that is no number shows
40
+ as it arrived. Null shows nothing.
41
+
42
+ ## Styling
43
+
44
+ The definition is a `<data>` whose text is the formatted number and whose
45
+ `value` is the number as it arrived. The hub stamps the tag with
46
+ `lb-column-value`, the number as it arrived, so a stylesheet selects on the
47
+ value itself:
48
+
49
+ ```css
50
+ lb-number[lb-column-value^="-"] {
51
+ color: var(--negative);
52
+ }
53
+ ```
@@ -0,0 +1,113 @@
1
+ # `lb-options`
2
+
3
+ A control wrapping an HTML `<select>`, with the `<option>`s coming from a
4
+ query.
5
+
6
+ Apply the `lb-query` attribute to name the query, `lb-column` to name the
7
+ column the choice shows and gathers to, and `lb-request` to name the request a
8
+ change issues. Write a `<template>` inside the tag, and apply `lb-column` to
9
+ the `<option>` itself — an `<option>` holds text, not elements. For options
10
+ in groups, write a group template holding an `<optgroup>`.
11
+
12
+ Provide `exp-label`.
13
+
14
+ ```html
15
+ <lb-options
16
+ lb-query="statuses"
17
+ lb-column="status_id"
18
+ exp-label="Status"
19
+ lb-request="setStatus"
20
+ >
21
+ <template lb-group>
22
+ <optgroup>
23
+ <template><option lb-column="label"></option></template>
24
+ </optgroup>
25
+ </template>
26
+ </lb-options>
27
+ ```
28
+
29
+ ## Status
30
+
31
+ Barebones starter to prove out the publish/consume chain and identify necessary
32
+ improvements through iterative use.
33
+
34
+ ## Parameters
35
+
36
+ | Parameter | Fills |
37
+ | ----------- | -------------------------- |
38
+ | `exp-label` | the visible `<label>` text |
39
+ | `exp-size` | the `<select>`'s `size`, an open list of that many rows rather than a drop-down |
40
+
41
+ ## Attributes
42
+
43
+ | Attribute | On | Names |
44
+ | ------------ | ------------------ | ------------------------------------------ |
45
+ | `lb-query` | the element itself | the query whose rows become options |
46
+ | `lb-column` | the element itself | the column the choice shows and gathers to |
47
+ | `lb-request` | the element itself | the request a change issues |
48
+ | `lb-group` | a template holding an `<optgroup>` | a group of options |
49
+ | `lb-column` | the `<option>` | the column the option shows |
50
+
51
+ The server declares the query's key. The widget copies each option's
52
+ `lb-key-value` to its `value`.
53
+
54
+ ## Grouping
55
+
56
+ The hub makes one `<optgroup>` per run of the query's order's leading term.
57
+ An `<optgroup>` takes its label from an attribute, which landing does not
58
+ set, so the widget labels each from the `lb-group-value` the hub stamps on
59
+ it: the value the group breaks on.
60
+
61
+ That value is often a number kept for sorting, such as a category's display
62
+ order, and a number is no label. For a label from a column of the group's
63
+ first row, write a heading option marked `data-group-label` in the
64
+ `<optgroup>`, filled like any group heading:
65
+
66
+ ```html
67
+ <template lb-group>
68
+ <optgroup>
69
+ <option data-group-label hidden disabled lb-column="category"></option>
70
+ <template><option lb-column="account_name"></option></template>
71
+ </optgroup>
72
+ </template>
73
+ ```
74
+
75
+ The widget takes the heading option's text as the label. Mark it `hidden`
76
+ and `disabled` so it is never a choice.
77
+
78
+ ## The control
79
+
80
+ `lb-options` is a form-associated custom element. Its `value` property gets
81
+ and sets the value of the `<select>` inside it, and it fires `change` on itself
82
+ when that `<select>` fires `change`. A form reset selects the first option.
83
+ A refusal's message for its column goes to the `<select>`, as HTML's own
84
+ validity.
85
+
86
+ The hub reads the element's own `lb-column` from the row around it, and lands
87
+ the rows of its `lb-query` inside it. A value set before the option it names
88
+ has landed selects that option when the rows land.
89
+
90
+ ## Choosing
91
+
92
+ With `lb-request`, the `lb-options` commits on `change`. The hub gathers its
93
+ value alone, the key of the chosen row, and sends the request with the `query`
94
+ and `key` of the row around it. Declare that request on the server, or name
95
+ `lb-row-update`.
96
+
97
+ Without `lb-request`, a change commits nothing, and the form or live row around
98
+ the `lb-options` gathers its value.
99
+
100
+ Inside `lb-query="lb-url"`, `lb-request="lb-row-update"` writes the chosen key
101
+ as a query parm, and the hub answers with no round trip.
102
+
103
+ While the request is in flight the hub marks the `lb-options` with
104
+ `lb-request-pending`, and on failure with `lb-request-error`. Both are there
105
+ for a stylesheet to read.
106
+
107
+ ## Styling an empty list
108
+
109
+ `lb-options` carries `lb-query-row-count` with the number of options showing,
110
+ for a stylesheet to read.
111
+
112
+ For the case where every row is one option and only the column names vary,
113
+ see [`lb-picker`](./lb-picker.md).
@@ -0,0 +1,53 @@
1
+ # `lb-picker`
2
+
3
+ [`lb-options`](./lb-options.md) with the row template built in, for when every
4
+ row is one option and only the column it shows varies. It takes no
5
+ children. Options in groups take a group template, which is `lb-options`
6
+ with the page's own templates.
7
+
8
+ Apply the `lb-query` attribute to name the query, `lb-column` to name the
9
+ column the choice shows and gathers to, and `lb-request` to name the request a
10
+ change issues.
11
+
12
+ Provide `exp-label` and `exp-column`.
13
+
14
+ ```html
15
+ <lb-picker
16
+ lb-query="statuses"
17
+ lb-column="status_id"
18
+ exp-label="Status"
19
+ exp-column="label"
20
+ lb-request="setStatus"
21
+ ></lb-picker>
22
+ ```
23
+
24
+ ## Status
25
+
26
+ Barebones starter to prove out the publish/consume chain and identify necessary
27
+ improvements through iterative use.
28
+
29
+ ## Parameters
30
+
31
+ | Parameter | Fills |
32
+ | ------------ | --------------------------- |
33
+ | `exp-label` | the visible `<label>` text |
34
+ | `exp-column` | the column the option shows |
35
+
36
+ `exp-column` is required. The server declares the query's key, which
37
+ becomes each option's `value`.
38
+
39
+ ## Attributes
40
+
41
+ | Attribute | Names |
42
+ | ------------ | ------------------------------------------ |
43
+ | `lb-query` | the query whose rows become options |
44
+ | `lb-column` | the column the choice shows and gathers to |
45
+ | `lb-request` | the request a change issues |
46
+
47
+ ## Choosing
48
+
49
+ The same as [`lb-options`](./lb-options.md): grouping, the key as the option's
50
+ value, the control's `value`, `lb-query-row-count`, and the request on change.
51
+
52
+ Write `lb-options` and the template instead for a row that needs a second
53
+ element, or an option built from two columns.
@@ -0,0 +1,70 @@
1
+ # `lb-select`
2
+
3
+ A control wrapping an HTML `<select>`, with the `<option>`s written by hand.
4
+
5
+ Apply the `lb-column` attribute to name the column, and `lb-request` to name the
6
+ request a change issues.
7
+
8
+ Provide `exp-label`.
9
+
10
+ ```html
11
+ <lb-select lb-column="status" exp-label="Status" lb-request="setStatus">
12
+ <option value="open">Open</option>
13
+ <option value="closed">Closed</option>
14
+ </lb-select>
15
+ ```
16
+
17
+ ## Status
18
+
19
+ Barebones starter to prove out the publish/consume chain and identify necessary
20
+ improvements through iterative use.
21
+
22
+ ## Parameters
23
+
24
+ | Parameter | Fills |
25
+ | ----------- | -------------------------- |
26
+ | `exp-label` | the visible `<label>` text |
27
+
28
+ ## Attributes
29
+
30
+ | Attribute | Names |
31
+ | ------------ | ------------------------------------------ |
32
+ | `lb-column` | the column the select shows and gathers to |
33
+ | `lb-request` | the request a change issues |
34
+
35
+ ## The control
36
+
37
+ `lb-select` is a form-associated custom element. Its `value` property gets
38
+ and sets the value of the `<select>` inside it, and it fires `change` on itself
39
+ when that `<select>` fires `change`. A form reset selects the option marked
40
+ `selected`, or the first option. A refusal's message for its column goes to
41
+ the `<select>`, as HTML's own validity.
42
+
43
+ ## Choosing
44
+
45
+ With `lb-request`, the `lb-select` commits on `change`. The hub gathers its
46
+ value alone and sends the request with the `query` and `key` of the row around
47
+ it, and `values` holding the chosen option's value under its column. Declare
48
+ that request on the server, or name `lb-row-update`.
49
+
50
+ Without `lb-request`, a change commits nothing, and the form or live row around
51
+ the `lb-select` gathers its value.
52
+
53
+ Inside `lb-query="lb-url"`, `lb-request="lb-row-update"` writes the choice as a
54
+ query parm, and the hub answers with no round trip.
55
+
56
+ ```html
57
+ <div lb-query="lb-url">
58
+ <lb-select lb-column="status" exp-label="Status" lb-request="lb-row-update">
59
+ <option value="">All</option>
60
+ <option value="open">Open</option>
61
+ </lb-select>
62
+ </div>
63
+ ```
64
+
65
+ While the request is in flight the hub marks the `lb-select` with
66
+ `lb-request-pending`, and on failure with `lb-request-error`. Both are there
67
+ for a stylesheet to read.
68
+
69
+ For a `<select>` whose options come from a query, see
70
+ [`lb-options`](./lb-options.md) and [`lb-picker`](./lb-picker.md).