Skip to content

[Platform-provided behaviors for CE] HTMLButtonBehavior with type attribute alternative - #1356

Open
anaskim wants to merge 5 commits into
MicrosoftEdge:mainfrom
anaskim:platform-provided-behaviors-type-attribute-alternative
Open

[Platform-provided behaviors for CE] HTMLButtonBehavior with type attribute alternative#1356
anaskim wants to merge 5 commits into
MicrosoftEdge:mainfrom
anaskim:platform-provided-behaviors-type-attribute-alternative

Conversation

@anaskim

@anaskim anaskim commented Jul 6, 2026

Copy link
Copy Markdown
Member

Not for merging, just getting comments/feedback in-line.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@anaskim
anaskim force-pushed the platform-provided-behaviors-type-attribute-alternative branch from 0d905bc to 92bcb54 Compare July 6, 2026 19:46
@anaskim
anaskim marked this pull request as ready for review July 6, 2026 19:49

@dandclark dandclark left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a first pass through, I like this. Just left some general early thoughts on the design.

Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@gregwhitworth gregwhitworth left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some general questions and primarily "nits". Thank you so much for your great work on this.

Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated

### Behavior categories and composition

Behaviors are organized into a set of categories. Categories are conceptual groupings the platform uses to decide which behaviors can coexist on one element. They are not classes exposed to authors; authors only ever reference the concrete behaviors (the leaves below).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slightlyoff raised at one point in this conversation why we're having abstractions. I think it's worth outlining why we're doing this bucketing rather than giving them more granular access. I personally like this design as I think 99% of authors are going to just want all of the goodness out of the box and also not have to keep adding capabilities as we introduce them into the platform (this is coming from years of having to support something similar) but it's worth noting (maybe in appendix or similar) why we're not currently exploring this path. I'm interested in @dandclark and your thoughts as this may also open a can of worms.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed this deserves to be written down. The granular / à-la-carte path (expose focusability, activation, form participation, etc. as independent primitives) is the low-level-primitives direction in Alternative 7 of the main explainer. When I move this alternative into the main explainer, I will leave the comments pointing to the granular approach.


Mapping a few native patterns onto categories helps validate the model:

| Native pattern | Behavior | Category | Notes |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really think this table is a great example of the power this provides

Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@anaskim anaskim left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the thorough feedback!

Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated

### Behavior categories and composition

Behaviors are organized into a set of categories. Categories are conceptual groupings the platform uses to decide which behaviors can coexist on one element. They are not classes exposed to authors; authors only ever reference the concrete behaviors (the leaves below).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed this deserves to be written down. The granular / à-la-carte path (expose focusability, activation, form participation, etc. as independent primitives) is the low-level-primitives direction in Alternative 7 of the main explainer. When I move this alternative into the main explainer, I will leave the comments pointing to the granular approach.

Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md Outdated
Comment thread PlatformProvidedBehaviors/htmlbuttonbehavior-with-type-attribute.md

@gregwhitworth gregwhitworth left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the edits, I'm a go :)

Ana Sollano Kim and others added 2 commits July 13, 2026 15:30
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour

Copy link
Copy Markdown

The premise of platform-provided behaviors is that authors delete JS and the platform runs the equivalent logic natively. If property and event surface still has to be forwarded in JS, that premise only half-holds, the code moves rather than disappears.

If the platform reflected a behavior's properties and events onto the host, bundle size/construction cost/access cost go to zero. No bytes shipped, no per-instance setup, native property access. That's the difference between "custom elements can approximate built-ins" and "custom elements can match built-ins."

I'd rather write something like this:

class MoSwitch extends HTMLElement {
  static formAssociated = true;
  static behaviors = [HTMLCheckboxBehavior];
}

And have e el.checked, el.indeterminate, and change/input just work, than write the same forwarding layer in every control, in every design system.

@anaskim

anaskim commented Jul 27, 2026

Copy link
Copy Markdown
Member Author

The premise of platform-provided behaviors is that authors delete JS and the platform runs the equivalent logic natively. If property and event surface still has to be forwarded in JS, that premise only half-holds, the code moves rather than disappears.

If the platform reflected a behavior's properties and events onto the host, bundle size/construction cost/access cost go to zero. No bytes shipped, no per-instance setup, native property access. That's the difference between "custom elements can approximate built-ins" and "custom elements can match built-ins."

I'd rather write something like this:

class MoSwitch extends HTMLElement {
  static formAssociated = true;
  static behaviors = [HTMLCheckboxBehavior];
}

And have e el.checked, el.indeterminate, and change/input just work, than write the same forwarding layer in every control, in every design system.

@mohamedmansour This is fair. I think Adobe also asked about this. I'd say if we can't offer this by default, there should be a way of opting-in and letting the browser do the reflection. Thanks for the comment, I'll take a look and discuss more.

@mohamedmansour

mohamedmansour commented Jul 27, 2026

Copy link
Copy Markdown

Thanks @anaskim, an opt-in would work for me. Two things that might help the discussion:

My preference is reflection on by default, because "behaves like a checkbox" is what an author asks for, and having to say so twice is a redundant. But an opt-in that's a single declaration is fine, the thing I want to avoid is per-property forwarding. Something like:

static behaviors = [HTMLCheckboxBehavior];
static reflectBehaviors = true;   // or per-behavior: [{ behavior: HTMLCheckboxBehavior, reflect: true }]

The reason to keep it opt-in is presumably name collisions, an author who already defines checked on their class, or wants different semantics. That argues for reflection being additive and losing to an own class member rather than throwing: if the class defines the property, the class wins, otherwise the platform installs it. That way opting in is safe and doesn't require auditing your class first.

Same question applies to events, I'd want input/change dispatching from the host without a re-dispatch layer, since a re-dispatched event isn't identical (composed/trusted/timing) and costs a listener per instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants