@loadbare/widgets 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +19 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +2 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/lb-mailto.browser.d.ts +2 -0
  7. package/dist/lb-mailto.browser.d.ts.map +1 -0
  8. package/dist/lb-mailto.browser.js +29 -0
  9. package/dist/lb-mailto.browser.js.map +1 -0
  10. package/dist/lb-mailto.html +6 -0
  11. package/dist/lb-tel.browser.d.ts +2 -0
  12. package/dist/lb-tel.browser.d.ts.map +1 -0
  13. package/dist/lb-tel.browser.js +40 -0
  14. package/dist/lb-tel.browser.js.map +1 -0
  15. package/dist/lb-tel.html +6 -0
  16. package/dist-cli/package-root.js +24 -0
  17. package/dist-cli/skills-cli.js +87 -0
  18. package/dist-cli/skills.js +125 -0
  19. package/docs/lb-checkbox.md +2 -2
  20. package/docs/lb-form.md +2 -2
  21. package/docs/lb-input.md +4 -2
  22. package/docs/lb-mailto.md +29 -0
  23. package/docs/lb-master.md +2 -2
  24. package/docs/lb-options.md +2 -0
  25. package/docs/lb-select.md +2 -1
  26. package/docs/lb-table.md +4 -3
  27. package/docs/lb-tel.md +32 -0
  28. package/docs/lb-unknown-page.md +2 -2
  29. package/package.json +12 -4
  30. package/skills/loadbare-widgets/SKILL.md +61 -0
  31. package/skills/loadbare-widgets/references/lb-checkbox.md +63 -0
  32. package/skills/loadbare-widgets/references/lb-confirm.md +44 -0
  33. package/skills/loadbare-widgets/references/lb-date.md +48 -0
  34. package/skills/loadbare-widgets/references/lb-form.md +35 -0
  35. package/skills/loadbare-widgets/references/lb-input.md +77 -0
  36. package/skills/loadbare-widgets/references/lb-insert-dialog.md +73 -0
  37. package/skills/loadbare-widgets/references/lb-mailto.md +29 -0
  38. package/skills/loadbare-widgets/references/lb-master.md +65 -0
  39. package/skills/loadbare-widgets/references/lb-number.md +53 -0
  40. package/skills/loadbare-widgets/references/lb-options.md +113 -0
  41. package/skills/loadbare-widgets/references/lb-picker.md +53 -0
  42. package/skills/loadbare-widgets/references/lb-select.md +70 -0
  43. package/skills/loadbare-widgets/references/lb-table.md +173 -0
  44. package/skills/loadbare-widgets/references/lb-tel.md +32 -0
  45. package/skills/loadbare-widgets/references/lb-unknown-page.md +43 -0
  46. package/docs/temp-feature-request-lb-table.md +0 -130
@@ -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).
@@ -0,0 +1,173 @@
1
+ # `lb-table`
2
+
3
+ A wrapper for HTML Table, supplying the `<table>` itself.
4
+
5
+ Apply the `lb-query` attribute to name the query. Write three `<template>`s
6
+ inside the tag: one marked `lb-exp-template="head"` for the heading row, one
7
+ unmarked for the row, or a group template holding it, and optionally one
8
+ marked `lb-exp-template="ghost"` for a ghost row and one marked
9
+ `lb-exp-template="foot"` for the footer. The query's order places the
10
+ rows.
11
+
12
+ Provide `exp-caption`.
13
+
14
+ ```html
15
+ <lb-table lb-query="ledger" exp-caption="Ledger">
16
+ <template lb-exp-template="head">
17
+ <tr><th>Date</th><th>Amount</th></tr>
18
+ </template>
19
+ <template lb-group>
20
+ <tr><th colspan="2" lb-column="month"></th></tr>
21
+ <template>
22
+ <tr><td lb-column="date"></td><td lb-column="amount"></td></tr>
23
+ </template>
24
+ </template>
25
+ <template lb-exp-template="foot">
26
+ <tr><td>Total</td><td lb-sum="amount"></td></tr>
27
+ </template>
28
+ </lb-table>
29
+ ```
30
+
31
+ Each part goes in a `<template>` because a `<thead>` or `<tr>` written
32
+ directly inside the tag is thrown away by the HTML parser.
33
+
34
+ ## Status
35
+
36
+ Barebones starter to prove out the publish/consume chain and identify necessary
37
+ improvements through iterative use.
38
+
39
+ ## Parameters
40
+
41
+ | Parameter | Fills |
42
+ | ------------- | -------------------- |
43
+ | `exp-caption` | the `<caption>` text |
44
+
45
+ ## Attributes
46
+
47
+ | Attribute | On | Names |
48
+ | ----------- | -------------------------------- | ---------------------------------- |
49
+ | `lb-query` | the element itself | the query whose rows fill the body |
50
+ | `lb-group` | a template holding the row template | a group, one per run of the order's leading term |
51
+ | `lb-order` | the element itself | the choice holding the user's order |
52
+ | `lb-filter` | the element itself | the columns the user's choices filter |
53
+ | `lb-column` | elements inside the row template | the column each element shows |
54
+
55
+ The server declares the query's key and its order.
56
+
57
+ ## Order and groups
58
+
59
+ The hub places the rows by the query's order and builds its groups. An
60
+ edit from a control in a row, or from the ghost row, leaves the rows where
61
+ they stand until the user asks for the order; a button with
62
+ `commandfor` naming the table's `id` and `command="--lb-sort"` does that.
63
+ The rows land in the table's one `<tbody>`, and a `<tbody>` cannot hold another,
64
+ so a group here is a heading row with its rows after it. For a `<tbody>` per
65
+ group, write a plain `<table lb-query>` whose group template is the
66
+ `<tbody>`.
67
+
68
+ `lb-order` and `lb-filter` work on `lb-table` as on any element carrying
69
+ `lb-query`: the user's order replaces the query's, and a row the user's
70
+ filter does not pass is hidden.
71
+
72
+ ## The order on the heading
73
+
74
+ The heading of the column the rows are sorted by carries a triangle, up for
75
+ ascending and down for descending, and `aria-sort`, read from the
76
+ `lb-query-order` the hub stamps on the table. Only the order's leading term
77
+ is shown. A heading's column is the `lb-column` in the cell
78
+ at the same position in the row template, on the cell or inside it. A cell
79
+ naming no column, or several, gives its heading none.
80
+
81
+ While rows stand out of order, the triangle carries `data-unsorted`, and a
82
+ click on its heading places them again, as `--lb-sort` does, keeping the
83
+ direction.
84
+
85
+ With `lb-order` on the table, a click on the sorted heading reverses the
86
+ order, and a click on another heading sorts by its column, ascending. The
87
+ widget writes the order to the column of `lb-choices` that `lb-order`
88
+ names. Without `lb-order` there is nowhere to write one, and only the
89
+ re-sort answers a click. There is no click back to the server's order.
90
+
91
+ A heading that takes a click carries `data-sortable`.
92
+
93
+ None of this shows on a grouped table, nor when the order's leading column
94
+ has no heading. There, a button with `commandfor` and `--lb-sort` does the
95
+ re-sort.
96
+
97
+ The package ships `lb-table.css`: the triangle turns amber and circled
98
+ while rows stand out of order, and the first cell of a row carrying
99
+ `lb-row-unsorted` is marked on its leading edge. The application's own
100
+ stylesheet comes after it and overrides any of it.
101
+
102
+ ## Filtering by selection
103
+
104
+ Text selected in a cell filters the table by that cell's column, when the
105
+ cell's `lb-column` is one the table's `lb-filter` names. On mouse-up the
106
+ widget writes the filter to that column of `lb-choices`, replacing whatever
107
+ it held, and clears the selection. Where the selection lies in the cell's
108
+ text picks the operator:
109
+
110
+ | Selected | Filter |
111
+ | ---------------------- | ------ |
112
+ | the whole text | `=` |
113
+ | from its start | `^=` |
114
+ | up to its end | `$=` |
115
+ | anywhere else | `*=` |
116
+
117
+ A control naming the same column of `lb-choices` shows the filter and
118
+ clears it.
119
+
120
+ ```html
121
+ <div lb-query="lb-choices">
122
+ <lb-input lb-column="payee" lb-request="lb-row-update" exp-label="Payee"></lb-input>
123
+ </div>
124
+
125
+ <lb-table lb-query="ledger" lb-filter="payee" exp-caption="Ledger">
126
+ ...
127
+ </lb-table>
128
+ ```
129
+
130
+ A selection reaching across two cells, or into a cell whose column the
131
+ table does not filter, is left alone.
132
+
133
+ ## The ghost row
134
+
135
+ The `ghost` template is a blank row for entering a new one, in a `<tbody>` of
136
+ its own between the rows and the footer. It is not a live row: the hub never
137
+ reconciles it and never counts it, and lands on whatever in it names a query.
138
+
139
+ ```html
140
+ <template lb-exp-template="ghost">
141
+ <tr>
142
+ <td><lb-input lb-column="name" exp-label="Name"></lb-input></td>
143
+ <td><button lb-request="lb-row-insert">Save</button></td>
144
+ </tr>
145
+ </template>
146
+ ```
147
+
148
+ A `<form>` cannot wrap a `<tr>`, so the widget makes one outside the table
149
+ and joins the row's controls and buttons to it with the `form` attribute. A
150
+ button carrying `lb-row-insert` submits that form, the hub gathers what the
151
+ form owns, and resets it once the insert succeeds. The widget then puts the
152
+ cursor back in the row's first control. A refused insert leaves the cursor
153
+ where it was.
154
+
155
+ ## Scrolling
156
+
157
+ After rows land, the widget scrolls into view the row the page's own request
158
+ created, or moved by changing a column the order reads.
159
+
160
+ ## The footer
161
+
162
+ The footer is an ordinary part of the page, not a row from the table's query.
163
+ An aggregate there covers every row showing. A figure that is not a sum of the rows,
164
+ such as a budget, is a `<tr>` with its own `lb-query`, a query of kind
165
+ `row` declared on the server like any other.
166
+
167
+ ## Styling an empty table
168
+
169
+ `lb-table` carries `lb-query-row-count` with the number of rows showing, for a
170
+ stylesheet to read.
171
+
172
+ For rows with no table of their own, write the row template inside any element
173
+ that carries `lb-query`.
@@ -0,0 +1,32 @@
1
+ # `lb-tel`
2
+
3
+ > Status: a barebones starter. Iterative use will drive improvements.
4
+
5
+ A phone number shown as written, as a `tel:` link. 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-tel lb-column="phone"></lb-tel>
11
+ ```
12
+
13
+ It takes no parameters. To edit the number, use
14
+ `<lb-input exp-type="tel">`.
15
+
16
+ ## The value
17
+
18
+ The link's text is the value as it arrived. Its `href` keeps a leading `+`
19
+ and the digits, and drops everything else, so `(555) 123-4567` dials
20
+ `tel:5551234567`.
21
+
22
+ An extension written after `x`, `ext`, `ext.` or `extension` goes in the
23
+ `href` as `;ext=`, so `555-123-4567 x89` dials `tel:5551234567;ext=89`.
24
+
25
+ A value with no digits shows as it arrived, with no `href`. Null shows
26
+ nothing.
27
+
28
+ ## Styling
29
+
30
+ The definition is an `<a>`, with no `href` while there is nothing to dial,
31
+ so `lb-tel a:not([href])` selects a number that is no link. The hub stamps
32
+ the tag with `lb-column-value`, the value as it arrived.
@@ -0,0 +1,43 @@
1
+ # `lb-unknown-page`
2
+
3
+ > Status: a barebones starter. Iterative use will drive improvements.
4
+
5
+ The chrome's dialog for a URL that names no page. Write it once, inside
6
+ `<lb-hub>`, and the hub opens it whenever no page's stub matches the path.
7
+
8
+ ```html
9
+ <lb-hub>
10
+ <nav>
11
+ <a href="/" lb-url-link>Home</a>
12
+ <a href="/about" lb-url-link>About</a>
13
+ </nav>
14
+ <main></main>
15
+ <lb-unknown-page></lb-unknown-page>
16
+ </lb-hub>
17
+ ```
18
+
19
+ ## Parameters
20
+
21
+ | Parameter | Fills |
22
+ | ----------------- | ------------------------------------- |
23
+ | `exp-button-text` | the text of the button that closes it |
24
+
25
+ Leaving `exp-button-text` off labels the button `OK`.
26
+
27
+ ## Binding
28
+
29
+ The definition supplies its own binding: a `<dialog lb-url-unknown>` carrying
30
+ `lb-query="lb-url"`, the query the hub serves and lands on every page load.
31
+
32
+ | Column | Holds |
33
+ | --------- | ------------------------ |
34
+ | `lb-path` | the path the browser has |
35
+
36
+ The widget shows the path. The dialog opens only when no page matches, so
37
+ there is no page label to show.
38
+
39
+ ## Inside the hub
40
+
41
+ The hub finds the dialog inside its own subtree and nowhere else, so the tag
42
+ goes inside `<lb-hub>`. The chrome reference of the loadbare-app skill shows
43
+ the same dialog written by hand in `chrome.html`.
@@ -1,130 +0,0 @@
1
- # Feature request: `lb-table` for maintenance pages
2
-
3
- Temporary. Written from the rkmedia app, which uses `lb-table` for every
4
- list it edits (lookup tables with a ghost row, edit-in-place cells,
5
- drag-to-reorder). Two things every such page wants and today writes for
6
- itself, or cannot have. To be settled here and then folded into
7
- `lb-table.md` or deleted.
8
-
9
- ## 1. The order shown on the heading, and re-sorted from it
10
-
11
- **Status:** first iteration implemented, as settled below; see
12
- `lb-table.md`, *The order on the heading*.
13
-
14
- **Want:** `lb-table` always marks the heading of the column the rows are
15
- sorted by with an up or down triangle for the direction. While the order is
16
- dirty from the user's edits (`lb-query-unsorted-count` is not 0), the
17
- triangle changes color. Clicking the heading sorts by its column.
18
-
19
- **Why:** an edit from a control in a row, or from the ghost row, leaves the
20
- rows where they stand (`lb-table.md`, *Order and groups*). Every table
21
- whose order reads a column the user edits needs a re-sort control, so every
22
- page writes the same markup and CSS. What rkmedia writes today:
23
-
24
- ```html
25
- <div class="list">
26
- <button type="button" class="resort" commandfor="workshop-topics-list" command="--lb-sort">Re-sort</button>
27
- <lb-table id="workshop-topics-list" lb-query="workshopTopics" exp-caption="Talks and workshops">
28
- ...
29
- </lb-table>
30
- </div>
31
- ```
32
-
33
- ```css
34
- .resort { visibility: hidden; }
35
- :has(> [lb-query-unsorted-count]:not([lb-query-unsorted-count="0"])) > .resort { visibility: visible; }
36
- ```
37
-
38
- The button cannot go inside the tag, so it needs an `id`, `commandfor` and
39
- a `:has()` on a wrapper. Shown with `display` it moves the table; shown
40
- with `visibility` it leaves a blank strip above every table.
41
-
42
- The heading row is always laid out and the widget owns it, so the
43
- triangle placed there moves nothing, needs no `id` and no page CSS. The
44
- hub already knows the order: the server declares it, and `lb-order` names
45
- the user's.
46
-
47
- **Settled:**
48
-
49
- - **The triangle is always shown** on the sorted column's heading, clean or
50
- dirty.
51
- - **Dirty is a color change** on the triangle.
52
- - **Clicking a dirty triangle re-sorts** (`--lb-sort`): it places the rows
53
- and clears `lb-row-unsorted`, keeping the direction. Only a click on a
54
- clean triangle reverses.
55
- - **Clicking another heading sorts by its column**, writing the user's
56
- order (`lb-order`). That places every row and clears `lb-row-unsorted`.
57
- - **Raw values.** A column shown formatted sorts by what the query sent,
58
- so it must be sent raw or declared in `types` (the reference already says
59
- so); worth repeating in `lb-table.md`.
60
- - **A default style for `tr[lb-row-unsorted]`** (rkmedia marks the first
61
- cell's left edge), subtle and overridable, saves every app writing one.
62
- - **A heading takes its column from the row template.** The nth heading
63
- shows the column of the nth cell of the row template, the `lb-column` in
64
- that cell. The page writes nothing on the `<th>`. A cell with no
65
- `lb-column`, or with several, gives its heading no column, and that
66
- heading does not sort.
67
- - **One column at a time.** A heading click writes an order of one term.
68
- When the order has several terms, the triangle marks the leading term.
69
- Sub-sorts are a UI question for later, built on this foundation.
70
- - **Groups leave all of this out.** A table with group templates shows no
71
- triangle and takes no heading clicks, so none of it triggers there.
72
- - **Dirty is yellow, circled.** The triangle turns yellow and gains a
73
- circle around it, so the shape says dirty without the color.
74
- - **No route back to the server's order.** Once the user sorts by a
75
- heading, the user's order stands.
76
- - **No sort is the opt-out.** A table with no order shows no triangle and
77
- takes no heading clicks.
78
-
79
- **Open:**
80
-
81
- - **The order's column not shown.** A drag-to-reorder table orders by a
82
- position column no one displays, and a server's order may lead with any
83
- column the template leaves out. No heading carries the triangle, so a
84
- dirty order has no re-sort control. Either the triangle has an
85
- always-present fallback, such tables keep a page-written button, or the
86
- dirty state cannot arise for them (a drag rewrites positions so no row
87
- stands out of order).
88
- - **Heading clicks without `lb-order`.** A heading click writes the user's
89
- order into the column of `lb-choices` that `lb-order` names. A table
90
- with a server order and no `lb-order` has nowhere to write it: it can
91
- show the triangle and re-sort from it, but not sort by another heading.
92
- Whether that is the intended reading of "no sort", or the widget
93
- supplies a choice of its own.
94
-
95
- The first iteration takes the plain reading of both: a table whose order's
96
- leading column has no heading shows no triangle and keeps a page-written
97
- button, and a table without `lb-order` shows the triangle and re-sorts
98
- from it but takes no clicks on other headings.
99
-
100
- ## 2. Highlight-to-filter that works on edit pages
101
-
102
- **Want:** select text in a cell and the table filters to the rows that
103
- match, on read-only and editable tables alike, and the table shows what it
104
- is filtered by.
105
-
106
- **What exists:** `lb-table.md`, *Filtering by selection*: a selection in a
107
- cell whose `lb-column` the table's `lb-filter` names becomes that column's
108
- choice (`=`, `^=`, `$=`, `*=`).
109
-
110
- **Gaps:**
111
-
112
- - **Inputs.** The widget reads `getSelection()`, which does not report text
113
- selected inside an `<input>` or `<textarea>`. An editable cell is an
114
- input, so on an edit page highlighting never filters. A control reports
115
- its own range (`selectionStart` / `selectionEnd`); the widget could read
116
- that when the selection is in one.
117
- - **Selecting is also editing.** In an input, selecting text is how you
118
- replace it, so filtering on every selection there would fight editing.
119
- It needs a gesture that means "filter": a modifier key held on mouse-up,
120
- or inputs that are `readonly`. Which gesture is Loadbare's call.
121
- - **No indicator.** Nothing on the table says it is filtered, by what, or
122
- offers to clear it; a page must add a control bound to `lb-choices`
123
- itself. With the re-sort on the heading, the caption line is free for
124
- this: the active filters with a clear button for each, and rows hidden
125
- ("12 of 40 shown"). Open whether the caption line is the place.
126
-
127
- ## Order of value to rkmedia
128
-
129
- 1, then 2. rkmedia has editable ordered tables now, will want heading
130
- sorts on the first long list, and has no filters yet.