face-up 0.0.1 → 0.0.2
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 +16 -19
- package/package.json +2 -2
- package/tests/test1.html +7 -22
- package/types/NewCustomElementFeature.md +2 -1
package/README.md
CHANGED
|
@@ -26,7 +26,13 @@ class MyInput extends HTMLElement {
|
|
|
26
26
|
static supportedFeatures = {
|
|
27
27
|
faceUp: {
|
|
28
28
|
fallbackSpawn: FaceUp,
|
|
29
|
-
callbackForwarding: [
|
|
29
|
+
callbackForwarding: [
|
|
30
|
+
'connectedCallback',
|
|
31
|
+
'disconnectedCallback',
|
|
32
|
+
'formDisabledCallback',
|
|
33
|
+
'formResetCallback',
|
|
34
|
+
'formStateRestoreCallback'
|
|
35
|
+
],
|
|
30
36
|
getSharedContext(instance) {
|
|
31
37
|
return {
|
|
32
38
|
internals: instance.#internals,
|
|
@@ -40,19 +46,6 @@ class MyInput extends HTMLElement {
|
|
|
40
46
|
super();
|
|
41
47
|
this.#internals = this.attachInternals();
|
|
42
48
|
}
|
|
43
|
-
|
|
44
|
-
// Forward form lifecycle callbacks to the feature
|
|
45
|
-
formDisabledCallback(disabled) {
|
|
46
|
-
this.faceUp.formDisabledCallback(disabled);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
formResetCallback() {
|
|
50
|
-
this.faceUp.formResetCallback();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
formStateRestoreCallback(state, mode) {
|
|
54
|
-
this.faceUp.formStateRestoreCallback(state, mode);
|
|
55
|
-
}
|
|
56
49
|
}
|
|
57
50
|
|
|
58
51
|
// assignFeatures calls FaceUp.onAssigned which sets static formAssociated = true
|
|
@@ -65,6 +58,8 @@ customElements.define('my-input', MyInput);
|
|
|
65
58
|
|
|
66
59
|
Note: `static formAssociated = true` is set automatically by `FaceUp.onAssigned` — you don't need to declare it yourself.
|
|
67
60
|
|
|
61
|
+
Form lifecycle callbacks (`formDisabledCallback`, `formResetCallback`, `formStateRestoreCallback`) are forwarded automatically via `callbackForwarding` — no manual forwarding code needed in the host element.
|
|
62
|
+
|
|
68
63
|
## Setting Values
|
|
69
64
|
|
|
70
65
|
Dispatch events on the host's `propagator` to update the form value:
|
|
@@ -138,23 +133,25 @@ The `state` is stored internally by the browser and passed back to `formStateRes
|
|
|
138
133
|
| `reportValidity()` | `boolean` | Shows browser validation UI if invalid |
|
|
139
134
|
| `setValidity(flags, message?, anchor?)` | `void` | Sets custom validity flags |
|
|
140
135
|
|
|
141
|
-
### Form Lifecycle
|
|
136
|
+
### Form Lifecycle Callbacks (forwarded via `callbackForwarding`)
|
|
142
137
|
|
|
143
|
-
|
|
|
144
|
-
|
|
138
|
+
| Callback | Description |
|
|
139
|
+
|----------|-------------|
|
|
145
140
|
| `formDisabledCallback(disabled)` | Called when disabled state changes |
|
|
146
141
|
| `formResetCallback()` | Called when the form is reset |
|
|
147
142
|
| `formStateRestoreCallback(state, mode)` | Called when browser restores form state |
|
|
148
143
|
|
|
144
|
+
These are forwarded automatically by `assign-gingerly`'s `callbackForwarding` mechanism — the host element does not need to implement them manually.
|
|
145
|
+
|
|
149
146
|
## Requirements
|
|
150
147
|
|
|
151
148
|
The host custom element **must**:
|
|
152
149
|
|
|
153
150
|
1. Call `this.attachInternals()` in its constructor
|
|
154
151
|
2. Pass the internals via `getSharedContext` in `supportedFeatures`
|
|
155
|
-
3.
|
|
152
|
+
3. Include the form lifecycle callbacks in `callbackForwarding`
|
|
156
153
|
|
|
157
|
-
`static formAssociated = true`
|
|
154
|
+
Both `static formAssociated = true` and form lifecycle callback forwarding are handled automatically — no manual boilerplate needed in the host element.
|
|
158
155
|
|
|
159
156
|
## Dev
|
|
160
157
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "face-up",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "A Custom Element Feature that Adds Form Associated Behavior to a Custom Element",
|
|
5
5
|
"homepage": "https://github.com/bahrus/face-up#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"chrome": "npx playwright cr http://localhost:8000"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"assign-gingerly": "0.0.
|
|
25
|
+
"assign-gingerly": "0.0.43",
|
|
26
26
|
"@playwright/test": "1.60.0",
|
|
27
27
|
"spa-ssi": "0.0.27"
|
|
28
28
|
},
|
package/tests/test1.html
CHANGED
|
@@ -20,7 +20,13 @@
|
|
|
20
20
|
static supportedFeatures = {
|
|
21
21
|
faceUp: {
|
|
22
22
|
fallbackSpawn: FaceUp,
|
|
23
|
-
callbackForwarding: [
|
|
23
|
+
callbackForwarding: [
|
|
24
|
+
'connectedCallback',
|
|
25
|
+
'disconnectedCallback',
|
|
26
|
+
'formDisabledCallback',
|
|
27
|
+
'formResetCallback',
|
|
28
|
+
'formStateRestoreCallback'
|
|
29
|
+
],
|
|
24
30
|
getSharedContext(instance) {
|
|
25
31
|
return {
|
|
26
32
|
internals: instance.#internals,
|
|
@@ -55,27 +61,6 @@
|
|
|
55
61
|
// Expose name for form submission
|
|
56
62
|
get name() { return this.getAttribute('name'); }
|
|
57
63
|
get type() { return this.localName; }
|
|
58
|
-
|
|
59
|
-
// Form lifecycle callbacks forwarded to the feature
|
|
60
|
-
formDisabledCallback(disabled) {
|
|
61
|
-
this.faceUp.formDisabledCallback(disabled);
|
|
62
|
-
const input = this.shadowRoot.querySelector('input');
|
|
63
|
-
input.disabled = disabled;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
formResetCallback() {
|
|
67
|
-
this.faceUp.formResetCallback();
|
|
68
|
-
const input = this.shadowRoot.querySelector('input');
|
|
69
|
-
input.value = '';
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
formStateRestoreCallback(state, mode) {
|
|
73
|
-
this.faceUp.formStateRestoreCallback(state, mode);
|
|
74
|
-
if (state) {
|
|
75
|
-
const input = this.shadowRoot.querySelector('input');
|
|
76
|
-
input.value = typeof state === 'string' ? state : '';
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
64
|
}
|
|
80
65
|
|
|
81
66
|
// Inject the FaceUp feature (onAssigned sets static formAssociated = true)
|
|
@@ -426,7 +426,7 @@ customElements.assignFeatures(MyElement, {
|
|
|
426
426
|
3. On first `connectedCallback`, the lazy getter is triggered — spawning the feature at the correct lifecycle moment (when the element is in the DOM and computed styles are available).
|
|
427
427
|
4. For async features, forwarding is skipped until the real instance is available.
|
|
428
428
|
|
|
429
|
-
**Supported callbacks:** `connectedCallback`, `disconnectedCallback`, `attributeChangedCallback`, `adoptedCallback`
|
|
429
|
+
**Supported callbacks:** `connectedCallback`, `disconnectedCallback`, `attributeChangedCallback`, `adoptedCallback`, `formAssociatedCallback`, `formDisabledCallback`, `formResetCallback`, `formStateRestoreCallback`
|
|
430
430
|
|
|
431
431
|
**When to use it:**
|
|
432
432
|
|
|
@@ -434,6 +434,7 @@ customElements.assignFeatures(MyElement, {
|
|
|
434
434
|
- The feature needs `getComputedStyle` (which requires the element to be in the DOM)
|
|
435
435
|
- The feature sets up event listeners that should be cleaned up on disconnect
|
|
436
436
|
- The feature needs to handle elements created via cloned templates (where the constructor fires before DOM insertion)
|
|
437
|
+
- The feature manages form-associated behavior (`formDisabledCallback`, `formResetCallback`, `formStateRestoreCallback`) — e.g., face-up
|
|
437
438
|
|
|
438
439
|
**Avoiding double-connect on initial spawn:**
|
|
439
440
|
|