@loadbare/app 0.17.0 → 0.18.1

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.
@@ -3,23 +3,31 @@ import { type ColumnTypes, type ResponseItem, type Row, type RowsResult } from "
3
3
  export interface Control extends Element {
4
4
  value: string;
5
5
  }
6
+ /**
7
+ * A radio button, whose state is `checked` as well. It is checked when its
8
+ * own `value` is the value that landed, so a group of them naming one column
9
+ * shows that value, and gathers the one checked.
10
+ */
11
+ export declare function isRadio(el: Element): boolean;
6
12
  /**
7
13
  * A form-associated custom element with a `value` property. HTML marks one
8
14
  * with `static formAssociated = true` on its class, and a control has a value.
9
15
  */
10
16
  export declare function isFormAssociated(el: Element): boolean;
11
17
  /**
12
- * A control: an `<input>`, `<select>` or `<textarea>`, a checkbox, or a
18
+ * A control: an `<input>`, `<select>` or `<textarea>`, a checkbox, a radio
19
+ * button, or a
13
20
  * form-associated custom element with a `value` property. Landing and
14
21
  * gathering draw the same line, so a value read back is the one that landed
15
22
  * there.
16
23
  */
17
24
  export declare function isControl(el: Element): el is Control;
18
25
  /**
19
- * What a control gathers: a checkbox `"true"` or `"false"`, so unchecked
20
- * still says so, and any other control its `value`.
26
+ * Gather a control into `values` under its column. Of the radio buttons
27
+ * naming one column, the one checked gives the value, and `""` stands when
28
+ * none is.
21
29
  */
22
- export declare function controlValue(el: Control): string;
30
+ export declare function gatherInto(values: Record<string, string>, column: string, el: Control): void;
23
31
  /**
24
32
  * Root if it matches, then every descendant in root's query that does.
25
33
  * Gathering finds columns through here. It does not reach into an absent
@@ -1 +1 @@
1
- {"version":3,"file":"lb-apply.d.ts","sourceRoot":"","sources":["../../hub/lb-apply.ts"],"names":[],"mappings":"AA+EA,OAAO,EASL,KAAK,WAAW,EAKhB,KAAK,YAAY,EACjB,KAAK,GAAG,EACR,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAyB7B,mEAAmE;AACnE,MAAM,WAAW,OAAQ,SAAQ,OAAO;IACtC,KAAK,EAAE,MAAM,CAAC;CACf;AA4BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAGrD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,OAAO,CAEpD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CAEhD;AAsFD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAMjE;AA0CD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI,CAGtD;AA6LD;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,GAAG,EACR,IAAI,UAAQ,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG,CAU3C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAKlE;AAQD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAS3C;AAwmBD,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,mDAAmD;IACnD,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CACvB,EAAE,EAAE,OAAO,EACX,QAAQ,EAAE,mBAAmB,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,WAAgB,GACxB,IAAI,CAgIN;AAmFD,uDAAuD;AACvD,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,GACZ,YAAY,GAAG,SAAS,CAE1B;AAgBD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAE7C;AAoGD,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,GAAE,WAAgB,GACxB,IAAI,CA2BN"}
1
+ {"version":3,"file":"lb-apply.d.ts","sourceRoot":"","sources":["../../hub/lb-apply.ts"],"names":[],"mappings":"AA+EA,OAAO,EASL,KAAK,WAAW,EAKhB,KAAK,YAAY,EACjB,KAAK,GAAG,EACR,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AA0B7B,mEAAmE;AACnE,MAAM,WAAW,OAAQ,SAAQ,OAAO;IACtC,KAAK,EAAE,MAAM,CAAC;CACf;AA4BD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAE5C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAGrD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,OAAO,CAIpD;AAUD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,OAAO,GACV,IAAI,CAMN;AA0FD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAMjE;AA0CD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI,CAGtD;AA6LD;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,GAAG,EACR,IAAI,UAAQ,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG,CAU3C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAKlE;AAQD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAS3C;AAsnBD,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,mDAAmD;IACnD,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CACvB,EAAE,EAAE,OAAO,EACX,QAAQ,EAAE,mBAAmB,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,WAAgB,GACxB,IAAI,CAgIN;AAmFD,uDAAuD;AACvD,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,GACZ,YAAY,GAAG,SAAS,CAE1B;AAgBD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAE7C;AAoGD,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,GAAE,WAAgB,GACxB,IAAI,CA2BN"}
@@ -49,7 +49,8 @@ const ELEMENT_NODE = 1;
49
49
  const TEXT_NODE = 3;
50
50
  /**
51
51
  * The input types whose state is not their `value`, or cannot be set. A
52
- * checkbox's state is `checked`, and it is a control by its own rule.
52
+ * checkbox's and a radio button's state is `checked`, and each is a control
53
+ * by its own rule.
53
54
  */
54
55
  const UNLANDED_INPUTS = ["checkbox", "radio", "file"];
55
56
  /**
@@ -73,6 +74,14 @@ function isNativeControl(el) {
73
74
  function isCheckbox(el) {
74
75
  return (el.localName === "input" && el.type === "checkbox");
75
76
  }
77
+ /**
78
+ * A radio button, whose state is `checked` as well. It is checked when its
79
+ * own `value` is the value that landed, so a group of them naming one column
80
+ * shows that value, and gathers the one checked.
81
+ */
82
+ export function isRadio(el) {
83
+ return el.localName === "input" && el.type === "radio";
84
+ }
76
85
  /**
77
86
  * A form-associated custom element with a `value` property. HTML marks one
78
87
  * with `static formAssociated = true` on its class, and a control has a value.
@@ -82,21 +91,34 @@ export function isFormAssociated(el) {
82
91
  return ctor.formAssociated === true && "value" in el;
83
92
  }
84
93
  /**
85
- * A control: an `<input>`, `<select>` or `<textarea>`, a checkbox, or a
94
+ * A control: an `<input>`, `<select>` or `<textarea>`, a checkbox, a radio
95
+ * button, or a
86
96
  * form-associated custom element with a `value` property. Landing and
87
97
  * gathering draw the same line, so a value read back is the one that landed
88
98
  * there.
89
99
  */
90
100
  export function isControl(el) {
91
- return isNativeControl(el) || isCheckbox(el) || isFormAssociated(el);
101
+ return (isNativeControl(el) || isCheckbox(el) || isRadio(el) || isFormAssociated(el));
92
102
  }
93
103
  /**
94
104
  * What a control gathers: a checkbox `"true"` or `"false"`, so unchecked
95
105
  * still says so, and any other control its `value`.
96
106
  */
97
- export function controlValue(el) {
107
+ function controlValue(el) {
98
108
  return isCheckbox(el) ? String(el.checked) : el.value;
99
109
  }
110
+ /**
111
+ * Gather a control into `values` under its column. Of the radio buttons
112
+ * naming one column, the one checked gives the value, and `""` stands when
113
+ * none is.
114
+ */
115
+ export function gatherInto(values, column, el) {
116
+ if (isRadio(el) && !el.checked) {
117
+ values[column] ??= "";
118
+ return;
119
+ }
120
+ values[column] = controlValue(el);
121
+ }
100
122
  /**
101
123
  * Set an element from a column. A control's `value` is set. A custom element
102
124
  * that is not a control keeps its content, which the builder placed there
@@ -107,8 +129,9 @@ function land(el, value) {
107
129
  // Untouched, whatever the server sent: the browser decides what a
108
130
  // non-string looks like. See Row in core/lb-types.ts.
109
131
  if (value === null || value === undefined) {
110
- if (isCheckbox(el))
132
+ if (isCheckbox(el) || isRadio(el)) {
111
133
  el.checked = false;
134
+ }
112
135
  else if (isControl(el))
113
136
  el.value = "";
114
137
  else if (!el.localName.includes("-") && el.localName !== "input") {
@@ -122,6 +145,10 @@ function land(el, value) {
122
145
  // and no string is read.
123
146
  el.checked = value !== false;
124
147
  }
148
+ else if (isRadio(el)) {
149
+ el.checked =
150
+ el.value === String(value);
151
+ }
125
152
  else if (isControl(el)) {
126
153
  el.value = value;
127
154
  }
@@ -587,6 +614,7 @@ function create(list, doc, key) {
587
614
  placed(el);
588
615
  el.setAttribute(ATTR_ROW_LIVE, "");
589
616
  el.setAttribute(ATTR_KEY_VALUE, key);
617
+ nameRadios(el, key);
590
618
  const entry = {
591
619
  key,
592
620
  el,
@@ -597,6 +625,18 @@ function create(list, doc, key) {
597
625
  list.byKey.set(key, entry);
598
626
  return entry;
599
627
  }
628
+ /**
629
+ * Give each radio button of a new live row a group of its own. The browser
630
+ * groups radio buttons by `name`, and a row template repeats one `name` in
631
+ * every live row, so the hub follows the `name` written, or the column when
632
+ * none is, with the row's key.
633
+ */
634
+ function nameRadios(row, key) {
635
+ for (const el of below(row, `input[type=radio][${ATTR_COLUMN}]`)) {
636
+ const name = el.getAttribute("name") || el.getAttribute(ATTR_COLUMN);
637
+ el.setAttribute("name", `${name}-${key}`);
638
+ }
639
+ }
600
640
  /** A group's identity among its siblings: its column and its value there. */
601
641
  function groupId(column, value) {
602
642
  return `${column}\u0000${JSON.stringify(value ?? null)}`;