Skip to content

fix(button)!: default to type="button" - #144

Open
pratikbuilds wants to merge 3 commits into
corbitsdev:mainfrom
pratikbuilds:claude/i142-button-type-4ccef8
Open

pratikbuilds wants to merge 3 commits into
corbitsdev:mainfrom
pratikbuilds:claude/i142-button-type-4ccef8

Conversation

@pratikbuilds

@pratikbuilds pratikbuilds commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Button renders a native <button>, and a <button> with no type is a submit button. Inside a host form, every bare Button submitted the form.

Button now defaults type to "button" when asChild is false. An omitted or undefined type still renders type="button". An explicit type still wins. asChild gets no injected type, since the slotted child may not be a button.

Breaking: a bare Button no longer submits a form. Pass type="submit" for a submit button.

Closes #142

@TheGreatAxios TheGreatAxios left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review · Request changes

Defaults native Button elements to type="button" when asChild is false so bare buttons inside host forms do not implicitly submit.

Findings

  • src/ui/button.tsx:80 — type={asChild ? undefined : "button"} is placed before {...props}, so a caller or wrapper that forwards { type: undefined } overwrites type="button" with undefined and renders a submit button (<button data-slot="button" ...>). Could we destructure type = asChild ? undefined : "button" in Button's parameters and pass type={type} so type={undefined} still defaults to "button"?
  • src/ui/button.test.tsx:30 (informational) — container.querySelector("button") as HTMLButtonElement (and lines 44, 62) uses as to silence | null rather than narrowing.

Button rendered a native <button> with no type, so HTML treated every
bare Button as a submit button: inside a host form, activating it
submitted the form. That is the stalled "Load earlier messages" control
in ConversationEarlier and the Retry control in SendStatusLine.

Button now renders type="button" unless a type is passed. asChild gets
no injected type, since the slotted child may not be a button.

BREAKING CHANGE: a bare Button no longer submits a form. Pass
type="submit" for a submit button.

Addresses corbitsdev#142 findings 8 and 9.
@pratikbuilds
pratikbuilds force-pushed the claude/i142-button-type-4ccef8 branch from 588d960 to a34c3bb Compare November 3, 2026 06:44

@corbits-triage corbits-triage Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Triage requests changes:

  • CI green: required checks are failing
    • policy-check

Drop the comment that restated the destructured type default.
Throw when a test query is not the expected element instead of
casting away null.

@corbits-triage corbits-triage Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Triage requests changes:

  • CI green: required checks are failing
    • policy-check

Slot spreads slot props over the child, so type={undefined} clears a
child type="button" and the click submits. Pass type only when it is
a string.

@corbits-triage corbits-triage Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Triage requests changes:

  • CI green: required checks are failing
    • policy-check

@TheGreatAxios TheGreatAxios left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approving. A native button with an omitted or undefined type renders type="button" and does not submit. asChild omits type unless the caller passed a real string, so a child that sets type="button" before spreading props keeps it.

@TheGreatAxios
TheGreatAxios dismissed stale reviews from corbits-triage[bot], corbits-triage[bot], and corbits-triage[bot] November 4, 2026 07:29

The type default is fixed and policy-check is green. Dismissing the stale triage change request.

@corbits-triage

corbits-triage Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Triage: Pass

No changes needed from you. A maintainer will review this pull request.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Follow-ups from the conversation PR review

2 participants