You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Trim explainer and rewrite type-attribute alternative
Tighten the main explainer's Properties section: remove the
attributeChangedCallback example and the form-override
mechanics table, both now redundant with the surrounding prose.
Drop a few minor qualifiers ("directly", "each pinned to a
single native pattern", "This proposal supports common web
component patterns:") that were not adding signal.
Rename the side document from
htmlbuttonbehavior-with-type-toggle.md to
htmlbuttonbehavior-with-type-attribute.md and rewrite it
around the static class declaration model:
- static behaviors = [HTMLButtonBehavior] declared at the
class level, read at customElements.define() time, mirroring
static formAssociated.
- The platform instantiates behaviors at element creation;
authors look up the instance through
internals.behaviors.get(HTMLButtonBehavior).
- HTMLButtonBehavior collapses submit, reset, and generic-button
into a single behavior whose type property toggles the active
mode at runtime.
- Properties section generalized from submit-only to all three
type values, with explicit qualifiers for type-conditional
behavior.
- Scenario table calls out commandfor/popovertarget short-circuit
semantics matching native button. Outside-a-form and
non-form-associated rows merged.
- Invalid type values are silently coerced to the default state
(submit), matching native button's invalid-value default.
- Feature detection mirrors the main explainer's branch
structure, translated to the static-declaration shape.
- WebIDL stub removed; explainer voice keeps IDL out of scope
(deferred to the design doc).
Copy file name to clipboardExpand all lines: PlatformProvidedBehaviors/explainer.md
+6-31Lines changed: 6 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -130,9 +130,9 @@ This proposal introduces `HTMLSubmitButtonBehavior`, which mirrors the submissio
130
130
131
131
### Behaviors are not opaque tokens
132
132
133
-
A recurring concern about consolidating form-control semantics into an opt-in is that web authors will not be able to figure out what a given opt-in actually does. This proposal addresses that concern directly:
133
+
A recurring concern about consolidating form-control semantics into an opt-in is that web authors will not be able to figure out what a given opt-in actually does. This proposal addresses that concern:
134
134
135
-
- Each element behavior maps to a single native pattern (e.g., `HTMLSubmitButtonBehavior` provides exactly the semantics of `<button type="submit">`). Future element behaviors will need to follow the same naming convention, each pinned to a single native pattern.
135
+
- Each element behavior maps to a single native pattern (e.g., `HTMLSubmitButtonBehavior` provides exactly the semantics of `<button type="submit">`). Future element behaviors will need to follow the same naming convention.
136
136
- Each behavior is specified in terms of existing HTML algorithms. The behavior is the union of those algorithms, applied to a custom element.
137
137
- Web authors can override individual defaults. This already works today for role: `internals.role` overrides a behavior's default role without replacing the behavior. The same layering pattern can extend to other defaults (focusability, keyboard activation, and similar) if and when future proposals add the corresponding primitives on `ElementInternals`. The [layering example in Alternative 7](#alternative-7-low-level-primitives-on-elementinternals) walks through what that would look like.
138
138
@@ -150,35 +150,12 @@ Each behavior exposes properties and methods from its corresponding native eleme
150
150
-`formTarget`
151
151
-`labels` - read-only, delegates to `ElementInternals.labels`
152
152
-`name`
153
-
-`title` - surfaced through the user agent's default tooltip UI, like native `<button>`.
153
+
-`title` - surfaced through the user agent's default tooltip UI
154
154
-`value`
155
155
156
-
To expose properties like `disabled` or `formAction` to external code, authors define getters and setters on the host that delegate to the behavior. See [Use case: Design system button](#use-case-design-system-button) for a complete worked example.
156
+
To expose these properties to external code, authors define getters and setters on the host that delegate to the behavior. See [Use case: Design system button](#use-case-design-system-button) for a complete worked example.
157
157
158
-
Authors are responsible for attribute reflection. If the author wants HTML attributes on their custom element to affect the `behavior`, they need to observe and forward those attributes using `attributeChangedCallback`:
Form override values (`formAction`, `formEnctype`, `formMethod`, `formNoValidate`, `formTarget`, `name`, `value`) are read from `behavior` properties. Setting a value declaratively in markup (e.g., `<my-button formaction="/save">`) or programmatically (e.g. `setAttribute('formaction', '/save')`) has no effect on form submission unless the author explicitly forwards that attribute to the `behavior`. However, some element attributes are applied to form submission as part of the existing [form-associated custom element](https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements) mechanism, independently of behaviors:
175
-
176
-
| Element attribute | Applied via form-associated custom element mechanics | Notes |
| `form` | Yes | Standard form association by ID. `behavior.form` is read-only and delegates to `ElementInternals.form`, which reflects this association. |
179
-
| `disabled` | Yes | Standard form control disabling. Combined with `behavior.disabled`. |
180
-
| `name`, `value` | No | Only `behavior.name` and `behavior.value` are read on submission. |
181
-
| `formaction`, `formenctype`, `formmethod`, `formtarget` | No | Only `behavior` properties are read. |
158
+
Form override values (`formAction`, `formEnctype`, `formMethod`, `formNoValidate`, `formTarget`, `name`, `value`) are read from `behavior` properties. Setting a value declaratively in markup (e.g., `<my-button formaction="/save">`) or programmatically (e.g. `setAttribute('formaction', '/save')`) has no effect on form submission unless the author explicitly forwards that attribute to the `behavior`. However, some element attributes are applied to form submission as part of the existing [form-associated custom element](https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements) mechanism.
182
159
183
160
### Behavior lifecycle
184
161
@@ -259,8 +236,6 @@ if (typeof HTMLSubmitButtonBehavior !== 'undefined') {
259
236
260
237
### Other considerations
261
238
262
-
This proposal supports common web component patterns:
263
-
264
239
- Custom elements using behaviors can follow progressive enhancement patterns: use `<slot>` to render fallback content, provide `<noscript>` alternatives, and design markup to be readable without JavaScript. If script fails to load, the element receives no behavior, which is true for any autonomous custom element with or without this proposal.
265
240
- Because behaviors are pinned to existing algorithms, this framework also enables polyfilling: authors can approximate new behaviors in *userland* before native support ships (see [Developer-defined behaviors](#developer-defined-behaviors) in [Future Work](#future-work)).
266
241
- While this proposal uses an imperative API, the design supports future declarative custom elements. Once a declarative syntax for `ElementInternals` is established, attaching behaviors could be modeled as an attribute, decoupling behavior from the JavaScript class definition. The following snippet shows a hypothetical example:
@@ -755,7 +730,7 @@ While valuable, this can be a parallel effort. Even if all native elements were
755
730
756
731
### Alternative 7: Low-level primitives on ElementInternals
757
732
758
-
Expose individual primitives directly on `ElementInternals`. Authors compose every native capability piece by piece.
733
+
Expose individual primitives on `ElementInternals`. Authors compose every native capability piece by piece.
759
734
760
735
**Pros:**
761
736
- Maximum flexibility: authors compose exactly what they need.
0 commit comments