@loadbare/widgets 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/control.d.ts +11 -0
- package/dist/control.d.ts.map +1 -1
- package/dist/control.js +17 -0
- package/dist/control.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/lb-checkbox.html +13 -0
- package/dist/lb-master.html +7 -2
- package/docs/lb-checkbox.md +63 -0
- package/docs/lb-form.md +5 -3
- package/docs/lb-master.md +15 -3
- package/package.json +2 -2
- package/dist/lb-form.browser.d.ts +0 -2
- package/dist/lb-form.browser.d.ts.map +0 -1
- package/dist/lb-form.browser.js +0 -28
- package/dist/lb-form.browser.js.map +0 -1
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ Inventory:
|
|
|
16
16
|
| [`lb-form`](docs/lb-form.md) | a form over one row, which saves per control once the row is on record |
|
|
17
17
|
| [`lb-insert-dialog`](docs/lb-insert-dialog.md) | a row entered in a modal dialog, chosen in the picker that opened it |
|
|
18
18
|
| [`lb-master`](docs/lb-master.md) | a set, one of its rows, and the buttons that act on the set |
|
|
19
|
+
| [`lb-checkbox`](docs/lb-checkbox.md) | a checkbox and its label, as markup to style |
|
|
19
20
|
|
|
20
21
|
## Installing
|
|
21
22
|
|
package/dist/control.d.ts
CHANGED
|
@@ -46,6 +46,17 @@ export declare abstract class WrappedControl extends HTMLElement {
|
|
|
46
46
|
* form its value once the control has been reset.
|
|
47
47
|
*/
|
|
48
48
|
formResetCallback(): void;
|
|
49
|
+
/**
|
|
50
|
+
* A message the hub sets when a handler refuses this control's column. It
|
|
51
|
+
* goes on the native control inside, which is what the form checks before
|
|
52
|
+
* it submits, what the browser shows the message beside, and what takes
|
|
53
|
+
* focus when it is reported.
|
|
54
|
+
*/
|
|
55
|
+
setCustomValidity(message: string): void;
|
|
56
|
+
/** Show the native control's message, and focus it. */
|
|
57
|
+
reportValidity(): boolean;
|
|
58
|
+
/** The native control's message, empty when it has none. */
|
|
59
|
+
get validationMessage(): string;
|
|
49
60
|
/** The inner control changed, before the widget fires its own `change`. */
|
|
50
61
|
protected changed(): void;
|
|
51
62
|
/** Tell the form owner the value, where the implementation allows it. */
|
package/dist/control.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../widgets/control.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,8BAAsB,cAAe,SAAQ,WAAW;IACtD,MAAM,CAAC,cAAc,UAAQ;IAE7B,uDAAuD;IACvD,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEjC;;;;OAIG;IACH,OAAO,CAAC,SAAS,CAAqB;IAEtC,6CAA6C;IAC7C,OAAO,CAAC,SAAS,CAAS;;IAY1B;;;;;;;;;OASG;IACH,iBAAiB,IAAI,IAAI;IASzB,8DAA8D;IAC9D,SAAS,KAAK,OAAO,IAAI,gBAAgB,GAAG,iBAAiB,GAAG,IAAI,CAEnE;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAUtB;IAED;;;;OAIG;IACH,iBAAiB,IAAI,IAAI;IAIzB,2EAA2E;IAC3E,SAAS,CAAC,OAAO,IAAI,IAAI;IAIzB,yEAAyE;IACzE,SAAS,CAAC,SAAS,IAAI,IAAI;CAG5B"}
|
|
1
|
+
{"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../widgets/control.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,8BAAsB,cAAe,SAAQ,WAAW;IACtD,MAAM,CAAC,cAAc,UAAQ;IAE7B,uDAAuD;IACvD,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEjC;;;;OAIG;IACH,OAAO,CAAC,SAAS,CAAqB;IAEtC,6CAA6C;IAC7C,OAAO,CAAC,SAAS,CAAS;;IAY1B;;;;;;;;;OASG;IACH,iBAAiB,IAAI,IAAI;IASzB,8DAA8D;IAC9D,SAAS,KAAK,OAAO,IAAI,gBAAgB,GAAG,iBAAiB,GAAG,IAAI,CAEnE;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAUtB;IAED;;;;OAIG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIxC,uDAAuD;IACvD,cAAc,IAAI,OAAO;IAIzB,4DAA4D;IAC5D,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,2EAA2E;IAC3E,SAAS,CAAC,OAAO,IAAI,IAAI;IAIzB,yEAAyE;IACzE,SAAS,CAAC,SAAS,IAAI,IAAI;CAG5B"}
|
package/dist/control.js
CHANGED
|
@@ -79,6 +79,23 @@ export class WrappedControl extends HTMLElement {
|
|
|
79
79
|
formResetCallback() {
|
|
80
80
|
queueMicrotask(() => this.formValue());
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* A message the hub sets when a handler refuses this control's column. It
|
|
84
|
+
* goes on the native control inside, which is what the form checks before
|
|
85
|
+
* it submits, what the browser shows the message beside, and what takes
|
|
86
|
+
* focus when it is reported.
|
|
87
|
+
*/
|
|
88
|
+
setCustomValidity(message) {
|
|
89
|
+
this.control?.setCustomValidity(message);
|
|
90
|
+
}
|
|
91
|
+
/** Show the native control's message, and focus it. */
|
|
92
|
+
reportValidity() {
|
|
93
|
+
return this.control?.reportValidity() ?? true;
|
|
94
|
+
}
|
|
95
|
+
/** The native control's message, empty when it has none. */
|
|
96
|
+
get validationMessage() {
|
|
97
|
+
return this.control?.validationMessage ?? "";
|
|
98
|
+
}
|
|
82
99
|
/** The inner control changed, before the widget fires its own `change`. */
|
|
83
100
|
changed() {
|
|
84
101
|
this.formValue();
|
package/dist/control.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.js","sourceRoot":"","sources":["../widgets/control.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAgB,cAAe,SAAQ,WAAW;IACtD,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;IAK7B;;;;OAIG;IACK,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAEtC,6CAA6C;IACrC,SAAS,GAAG,KAAK,CAAC;IAE1B;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACpC,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO;gBAAE,OAAO;YAC3D,CAAC,CAAC,eAAe,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACH,iBAAiB;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,IAAI,KAAK,IAAI;YAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QACrD,IAAI,OAAO,KAAK,IAAI;YAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC;IAC7C,CAAC;IAED,8DAA8D;IAC9D,IAAc,OAAO;QACnB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,IAAI,KAAK,CAAC,KAAa;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,GAAG,IAAI,CAAC,SAAS,SAAS,IAAI,CAAC,KAAK,wBAAwB,CAC7D,CAAC;YACF,OAAO;QACT,CAAC;QACD,OAAO,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,iBAAiB;QACf,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,2EAA2E;IACjE,OAAO;QACf,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,yEAAyE;IAC/D,SAAS;QACjB,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;;AAGH,SAAS,WAAW,CAAC,EAAe;IAClC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC;QACvC,OAAO,OAAO,SAAS,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["/// <reference lib=\"dom\" />\n\nimport { ATTR_COLUMN_VALUE } from \"@loadbare/app/constants\";\n\n/**\n * A form-associated custom element wrapping one native control, which makes\n * the widget itself the control: the hub sets its `value` when a column\n * lands, reads it back when a request gathers, and commits it on `change`\n * when it carries `lb-request`. Nothing about a request is the widget's.\n *\n * The native control inside is an implementation detail. Its `change` is\n * stopped and fired again on the widget, so a listener sees one control and\n * one event per edit.\n *\n * Not a widget itself, so the file carries no `.browser` and no `lb-` name:\n * a consumer's builder passes it over, and each widget that extends it\n * brings it along.\n */\nexport abstract class WrappedControl extends HTMLElement {\n static formAssociated = true;\n\n /** The tag of the native control this widget wraps. */\n protected abstract inner: string;\n\n /**\n * Null where the DOM implementation offers no form value, which includes\n * jsdom: the widget still works as a control, and a native form submission\n * leaves it out.\n */\n private internals = internalsOf(this);\n\n /** Whether the widget has connected once. */\n private connected = false;\n\n constructor() {\n super();\n this.addEventListener(\"change\", (e) => {\n if (e.target === this || e.target !== this.control) return;\n e.stopPropagation();\n this.changed();\n this.dispatchEvent(new Event(\"change\", { bubbles: true }));\n });\n }\n\n /**\n * A value that landed before this widget's definition did is only a\n * stamp, since the hub sets `value` on a control and the element was not\n * one yet. It is taken up the first time the widget connects, and never\n * again: after that the hub sets `value` itself, and a later move must not\n * undo an edit.\n *\n * The native control follows the widget's `form` attribute, so a form\n * this widget joins by id resets the control inside it too.\n */\n connectedCallback(): void {\n const form = this.getAttribute(\"form\");\n if (form !== null) this.control?.setAttribute(\"form\", form);\n if (this.connected) return;\n this.connected = true;\n const stamped = this.getAttribute(ATTR_COLUMN_VALUE);\n if (stamped !== null) this.value = stamped;\n }\n\n /** The native control this widget wraps, once it is there. */\n protected get control(): HTMLInputElement | HTMLSelectElement | null {\n return this.querySelector(this.inner);\n }\n\n get value(): string {\n return this.control?.value ?? \"\";\n }\n\n set value(value: string) {\n const control = this.control;\n if (!control) {\n console.error(\n `${this.localName}: no <${this.inner}> to receive the value`,\n );\n return;\n }\n control.value = value ?? \"\";\n this.formValue();\n }\n\n /**\n * The native control is the form's too, and the form resets it by HTML's\n * own algorithm. This widget comes first in tree order, so it tells the\n * form its value once the control has been reset.\n */\n formResetCallback(): void {\n queueMicrotask(() => this.formValue());\n }\n\n /** The inner control changed, before the widget fires its own `change`. */\n protected changed(): void {\n this.formValue();\n }\n\n /** Tell the form owner the value, where the implementation allows it. */\n protected formValue(): void {\n this.internals?.setFormValue(this.value);\n }\n}\n\nfunction internalsOf(el: HTMLElement): ElementInternals | null {\n try {\n const internals = el.attachInternals();\n return typeof internals.setFormValue === \"function\" ? internals : null;\n } catch {\n return null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"control.js","sourceRoot":"","sources":["../widgets/control.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference lib=\"dom\" />\n\nimport { ATTR_COLUMN_VALUE } from \"@loadbare/app/constants\";\n\n/**\n * A form-associated custom element wrapping one native control, which makes\n * the widget itself the control: the hub sets its `value` when a column\n * lands, reads it back when a request gathers, and commits it on `change`\n * when it carries `lb-request`. Nothing about a request is the widget's.\n *\n * The native control inside is an implementation detail. Its `change` is\n * stopped and fired again on the widget, so a listener sees one control and\n * one event per edit.\n *\n * Not a widget itself, so the file carries no `.browser` and no `lb-` name:\n * a consumer's builder passes it over, and each widget that extends it\n * brings it along.\n */\nexport abstract class WrappedControl extends HTMLElement {\n static formAssociated = true;\n\n /** The tag of the native control this widget wraps. */\n protected abstract inner: string;\n\n /**\n * Null where the DOM implementation offers no form value, which includes\n * jsdom: the widget still works as a control, and a native form submission\n * leaves it out.\n */\n private internals = internalsOf(this);\n\n /** Whether the widget has connected once. */\n private connected = false;\n\n constructor() {\n super();\n this.addEventListener(\"change\", (e) => {\n if (e.target === this || e.target !== this.control) return;\n e.stopPropagation();\n this.changed();\n this.dispatchEvent(new Event(\"change\", { bubbles: true }));\n });\n }\n\n /**\n * A value that landed before this widget's definition did is only a\n * stamp, since the hub sets `value` on a control and the element was not\n * one yet. It is taken up the first time the widget connects, and never\n * again: after that the hub sets `value` itself, and a later move must not\n * undo an edit.\n *\n * The native control follows the widget's `form` attribute, so a form\n * this widget joins by id resets the control inside it too.\n */\n connectedCallback(): void {\n const form = this.getAttribute(\"form\");\n if (form !== null) this.control?.setAttribute(\"form\", form);\n if (this.connected) return;\n this.connected = true;\n const stamped = this.getAttribute(ATTR_COLUMN_VALUE);\n if (stamped !== null) this.value = stamped;\n }\n\n /** The native control this widget wraps, once it is there. */\n protected get control(): HTMLInputElement | HTMLSelectElement | null {\n return this.querySelector(this.inner);\n }\n\n get value(): string {\n return this.control?.value ?? \"\";\n }\n\n set value(value: string) {\n const control = this.control;\n if (!control) {\n console.error(\n `${this.localName}: no <${this.inner}> to receive the value`,\n );\n return;\n }\n control.value = value ?? \"\";\n this.formValue();\n }\n\n /**\n * The native control is the form's too, and the form resets it by HTML's\n * own algorithm. This widget comes first in tree order, so it tells the\n * form its value once the control has been reset.\n */\n formResetCallback(): void {\n queueMicrotask(() => this.formValue());\n }\n\n /**\n * A message the hub sets when a handler refuses this control's column. It\n * goes on the native control inside, which is what the form checks before\n * it submits, what the browser shows the message beside, and what takes\n * focus when it is reported.\n */\n setCustomValidity(message: string): void {\n this.control?.setCustomValidity(message);\n }\n\n /** Show the native control's message, and focus it. */\n reportValidity(): boolean {\n return this.control?.reportValidity() ?? true;\n }\n\n /** The native control's message, empty when it has none. */\n get validationMessage(): string {\n return this.control?.validationMessage ?? \"\";\n }\n\n /** The inner control changed, before the widget fires its own `change`. */\n protected changed(): void {\n this.formValue();\n }\n\n /** Tell the form owner the value, where the implementation allows it. */\n protected formValue(): void {\n this.internals?.setFormValue(this.value);\n }\n}\n\nfunction internalsOf(el: HTMLElement): ElementInternals | null {\n try {\n const internals = el.attachInternals();\n return typeof internals.setFormValue === \"function\" ? internals : null;\n } catch {\n return null;\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../widgets/index.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../widgets/index.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO,+BAA+B,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../widgets/index.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../widgets/index.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO,+BAA+B,CAAC","sourcesContent":["import \"./lb-input.browser.js\";\nimport \"./lb-select.browser.js\";\nimport \"./lb-options.browser.js\";\nimport \"./lb-table.browser.js\";\nimport \"./lb-picker.browser.js\";\nimport \"./lb-confirm.browser.js\";\nimport \"./lb-insert-dialog.browser.js\";\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
A checkbox with its label, as markup alone. The hub treats a native
|
|
3
|
+
checkbox as a control, so there is nothing for script to do: the widget
|
|
4
|
+
gives the box and its text one element an application styles.
|
|
5
|
+
|
|
6
|
+
The column and request go on the checkbox inside, since that is the
|
|
7
|
+
control, so they arrive as exp-column and exp-request rather than as
|
|
8
|
+
lb-column and lb-request on the tag.
|
|
9
|
+
-->
|
|
10
|
+
<label>
|
|
11
|
+
<input type="checkbox" lb-column="{{column}}" lb-request="{{request}}" />
|
|
12
|
+
<span>{{label}}</span>
|
|
13
|
+
</label>
|
package/dist/lb-master.html
CHANGED
|
@@ -9,8 +9,10 @@
|
|
|
9
9
|
belongs to.
|
|
10
10
|
|
|
11
11
|
The standard bar is [New] [Copy] [Delete] [Save new] [Cancel].
|
|
12
|
-
- New is
|
|
13
|
-
|
|
12
|
+
- New is a request the page declares, `new`. Which row shows is a query
|
|
13
|
+
parm, and a button writes none, so the page's handler returns url()
|
|
14
|
+
emptying the parm, and the row query answers a row not yet entered.
|
|
15
|
+
It pushes a history entry, so Back returns to the row on record.
|
|
14
16
|
- Copy is a request the page declares, `copy`. It goes to the server by
|
|
15
17
|
design rather than filling the form for Save new: a copy is a new row in
|
|
16
18
|
the set, and only the server can bring its children along. What comes
|
|
@@ -25,6 +27,9 @@
|
|
|
25
27
|
<div class="lb-master-row" lb-query="{{row}}">
|
|
26
28
|
<lb-form exp-id="{{form-id|master-form}}" lb-exp-slot></lb-form>
|
|
27
29
|
<div class="lb-master-buttons">
|
|
30
|
+
<button type="button" lb-request="new" lb-url-push data-mode="on-record">
|
|
31
|
+
New
|
|
32
|
+
</button>
|
|
28
33
|
<button type="button" lb-request="copy" data-mode="on-record">Copy</button>
|
|
29
34
|
<lb-confirm
|
|
30
35
|
exp-label="Delete"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# `lb-checkbox`
|
|
2
|
+
|
|
3
|
+
> Status: a barebones starter. Iterative use will drive improvements.
|
|
4
|
+
|
|
5
|
+
A checkbox and its label as one element, for an application to style. A
|
|
6
|
+
definition only, with no script: the hub treats a native checkbox as a
|
|
7
|
+
control, so the widget adds nothing but the markup.
|
|
8
|
+
|
|
9
|
+
Requires `exp-column` and `exp-label`.
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<div lb-query="people">
|
|
13
|
+
<template>
|
|
14
|
+
<div>
|
|
15
|
+
<lb-checkbox exp-column="active" exp-label="Active" exp-request="lb-row-update"></lb-checkbox>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
</div>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Expansion Attributes
|
|
22
|
+
|
|
23
|
+
| Parameter | Fills |
|
|
24
|
+
| ------------- | ----------------------------------------------- |
|
|
25
|
+
| `exp-column` | the checkbox's `lb-column` |
|
|
26
|
+
| `exp-label` | the label's text |
|
|
27
|
+
| `exp-request` | the checkbox's `lb-request`, none when absent |
|
|
28
|
+
|
|
29
|
+
The column and request go on the checkbox inside, since it is the control,
|
|
30
|
+
so they are expansion attributes here rather than `lb-column` and
|
|
31
|
+
`lb-request` on the tag.
|
|
32
|
+
|
|
33
|
+
## Why it is not like `lb-input`
|
|
34
|
+
|
|
35
|
+
`lb-input` has a script that makes the tag itself the control, so the page
|
|
36
|
+
writes `lb-column` on the tag. `lb-checkbox` cannot do the same. A value
|
|
37
|
+
that lands before a widget's script has loaded reaches it only as the
|
|
38
|
+
`lb-column-value` stamp, a string, and a checkbox's state is a boolean. A
|
|
39
|
+
script `lb-checkbox` would read the stamp `"false"` as checked, since no
|
|
40
|
+
string is read. The native checkbox has no such gap: the hub sets `checked`
|
|
41
|
+
on it directly.
|
|
42
|
+
|
|
43
|
+
`lb-input` could equally be markup alone; its script is a convention, kept
|
|
44
|
+
for now.
|
|
45
|
+
|
|
46
|
+
## The control
|
|
47
|
+
|
|
48
|
+
The checkbox is checked when its column is anything but `false` or null, and
|
|
49
|
+
sends `"true"` or `"false"`. See
|
|
50
|
+
[checkboxes](../../app/docs/reference/data-binding.md#checkboxes).
|
|
51
|
+
|
|
52
|
+
## Styling
|
|
53
|
+
|
|
54
|
+
The definition is a `<label>` holding the `<input type="checkbox">` and a
|
|
55
|
+
`<span>` with the text:
|
|
56
|
+
|
|
57
|
+
```css
|
|
58
|
+
lb-checkbox label {
|
|
59
|
+
display: inline-flex;
|
|
60
|
+
gap: 0.5em;
|
|
61
|
+
align-items: center;
|
|
62
|
+
}
|
|
63
|
+
```
|
package/docs/lb-form.md
CHANGED
|
@@ -25,9 +25,11 @@ Requires `exp-id`.
|
|
|
25
25
|
|
|
26
26
|
A row with a key is on record, and each control saves its own column on
|
|
27
27
|
`change` with `lb-request="lb-row-update"`. A row whose key is empty is a new
|
|
28
|
-
one not yet entered:
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
one not yet entered: the hub sends no update for it, so the controls only
|
|
29
|
+
hold what a submit will gather. See
|
|
30
|
+
[a row not yet entered](../../app/docs/reference/data-binding.md#a-row-not-yet-entered).
|
|
31
|
+
|
|
32
|
+
A definition only, with no script of its own.
|
|
31
33
|
|
|
32
34
|
A button that acts on the row as a whole, such as one adding it to the set,
|
|
33
35
|
belongs to whatever holds the set, and reaches the form by `form="<id>"`.
|
package/docs/lb-master.md
CHANGED
|
@@ -39,15 +39,27 @@ Requires `exp-row`.
|
|
|
39
39
|
|
|
40
40
|
| Button | Shows | Does |
|
|
41
41
|
| -------- | ----------------- | --------------------------------------------- |
|
|
42
|
+
| New | A row on record | Sends `new`, a request the page declares, and pushes a history entry |
|
|
42
43
|
| Copy | A row on record | Sends `copy`, a request the page declares |
|
|
43
44
|
| Delete | A row on record | Asks, then sends `lb-row-delete` |
|
|
44
45
|
| Save new | A new row | Submits the form as `lb-row-insert`, and pushes a history entry |
|
|
45
46
|
| Cancel | A new row | Resets the form |
|
|
46
47
|
|
|
47
48
|
Each carries `data-mode`, `on-record` or `new`, and the stylesheet shows each
|
|
48
|
-
only in its mode. A new row is one whose key is empty
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
only in its mode. A new row is one whose key is empty, a
|
|
50
|
+
[row not yet entered](../../app/docs/reference/data-binding.md#a-row-not-yet-entered).
|
|
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.
|
|
51
63
|
|
|
52
64
|
Copy goes to the server rather than filling the form, because a copy is a new
|
|
53
65
|
row in the set, and only the server can bring its children along.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loadbare/widgets",
|
|
3
|
-
"description": "The basic widget set for @loadbare/app: input, select, options, picker, table, unknown-page, confirm, form, insert-dialog, master",
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "The basic widget set for @loadbare/app: input, select, options, picker, table, unknown-page, confirm, form, insert-dialog, master, checkbox",
|
|
4
|
+
"version": "0.7.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lb-form.browser.d.ts","sourceRoot":"","sources":["../widgets/lb-form.browser.ts"],"names":[],"mappings":""}
|
package/dist/lb-form.browser.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
|
-
import { LB_EVENT_NAME, REQUEST_ROW_UPDATE } from "@loadbare/app/constants";
|
|
3
|
-
/**
|
|
4
|
-
* A form over one row, in one of two modes that the row decides.
|
|
5
|
-
*
|
|
6
|
-
* A row with a key is on record, and each control saves its own column on
|
|
7
|
-
* `change`: the page writes `lb-request="lb-row-update"` on every control.
|
|
8
|
-
* A row with an empty key is a new one not yet entered, and a change saves
|
|
9
|
-
* nothing, because there is nothing to update; the controls only hold what
|
|
10
|
-
* will be gathered when something submits the form.
|
|
11
|
-
*
|
|
12
|
-
* So the form stops an update whose key came back empty. The hub completes a
|
|
13
|
-
* request on the way down, before any ancestor sees it, so the key is already
|
|
14
|
-
* in `detail` when the event bubbles through here.
|
|
15
|
-
*/
|
|
16
|
-
class LbForm extends HTMLElement {
|
|
17
|
-
constructor() {
|
|
18
|
-
super();
|
|
19
|
-
this.addEventListener(LB_EVENT_NAME, (e) => {
|
|
20
|
-
const request = e.detail;
|
|
21
|
-
if (request.name === REQUEST_ROW_UPDATE && request.key === "") {
|
|
22
|
-
e.stopPropagation();
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
customElements.define("lb-form", LbForm);
|
|
28
|
-
//# sourceMappingURL=lb-form.browser.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lb-form.browser.js","sourceRoot":"","sources":["../widgets/lb-form.browser.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG5E;;;;;;;;;;;;GAYG;AACH,MAAM,MAAO,SAAQ,WAAW;IAC9B;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE;YACzC,MAAM,OAAO,GAAI,CAA6B,CAAC,MAAM,CAAC;YACtD,IAAI,OAAO,CAAC,IAAI,KAAK,kBAAkB,IAAI,OAAO,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC;gBAC9D,CAAC,CAAC,eAAe,EAAE,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC","sourcesContent":["/// <reference lib=\"dom\" />\n\nimport { LB_EVENT_NAME, REQUEST_ROW_UPDATE } from \"@loadbare/app/constants\";\nimport type { HubRequest } from \"@loadbare/app/types\";\n\n/**\n * A form over one row, in one of two modes that the row decides.\n *\n * A row with a key is on record, and each control saves its own column on\n * `change`: the page writes `lb-request=\"lb-row-update\"` on every control.\n * A row with an empty key is a new one not yet entered, and a change saves\n * nothing, because there is nothing to update; the controls only hold what\n * will be gathered when something submits the form.\n *\n * So the form stops an update whose key came back empty. The hub completes a\n * request on the way down, before any ancestor sees it, so the key is already\n * in `detail` when the event bubbles through here.\n */\nclass LbForm extends HTMLElement {\n constructor() {\n super();\n this.addEventListener(LB_EVENT_NAME, (e) => {\n const request = (e as CustomEvent<HubRequest>).detail;\n if (request.name === REQUEST_ROW_UPDATE && request.key === \"\") {\n e.stopPropagation();\n }\n });\n }\n}\n\ncustomElements.define(\"lb-form\", LbForm);\n"]}
|