Skip to content

feat(ui): default Button to type='button' and forward refs on Button,… - #17

Merged
Mona-i merged 2 commits into
lumio-network:mainfrom
starfishkrq:feature/6-7-button-default-type-and-forwardrefs
Sep 10, 2026
Merged

Mona-i merged 2 commits into
lumio-network:mainfrom
starfishkrq:feature/6-7-button-default-type-and-forwardrefs

Conversation

@starfishkrq

Copy link
Copy Markdown
Contributor

feat(ui): default Button to type="button" and forward refs on Button, Input, Card

closes #6
closes #7


What and why

Two small but impactful improvements to the UI primitives in @lumio/ui.

#6 — Default Button to type="button"

An HTML <button> with no type attribute defaults to type="submit" per the spec. That means any <Button> placed inside a <form> will submit the form on click — even when it was only meant to trigger a client-side action. This is a silent footgun that is easy to introduce and hard to debug.

The fix is a one-line default: type = "button". Callers who need type="submit" or type="reset" still pass it explicitly and it wins, so no existing behaviour is broken.

#7forwardRef on Button, Input, and Card

The primitives were plain function components with no ref support. Without forwardRef, consumers cannot:

  • call inputRef.current?.focus() for focus management
  • pass a ref from react-hook-form's register or Controller
  • use scrollIntoView on a card

For a design-system package meant to be consumed by product apps, ref forwarding is table stakes. This change wraps every component (including CardTitle and CardBody) with React.forwardRef, types the ref to the correct DOM element, and sets displayName on each so React DevTools remains readable.


Changes

File What changed
packages/ui/src/components/Button.tsx forwardRef<HTMLButtonElement>, type = "button" default, displayName = "Button"
packages/ui/src/components/Input.tsx forwardRef<HTMLInputElement>, displayName = "Input"
packages/ui/src/components/Card.tsx forwardRef on Card, CardTitle, and CardBody with correct element types; displayName on all three
packages/ui/src/ui.test.tsx 3 new tests — Button default type, Button ref forwarding, Input ref forwarding

No new dependencies. No API changes. All existing prop signatures are preserved.


Tests

✓ cn › joins truthy class names and drops falsy ones
✓ Button › renders its children and forwards the type attribute
✓ Button › applies the primary (lumen) variant by default
✓ Button › defaults to type="button" when no type is provided       ← new (#6)
✓ Button › forwards a ref to the underlying <button> element        ← new (#7)
✓ Input  › forwards a ref to the underlying <input> element         ← new (#7)
✓ Badge  › uses the requested semantic variant

Test Files  1 passed (1)
     Tests  7 passed (7)

Validation

Check Result
npm run typecheck ✅ exit 0
npm run test ✅ 7/7 passed
npm run build ✅ exit 0

Out of scope

  • No restyle or variant changes.
  • No new components added.
  • No dependency additions.

… Input, Card

- Button now defaults to type='button' to prevent accidental form
  submissions when no type prop is provided (closes #6)
- Wrapped Button, Input, Card, CardTitle, and CardBody with
  React.forwardRef, typing refs to HTMLButtonElement, HTMLInputElement,
  and HTMLDivElement/HTMLHeadingElement/HTMLParagraphElement respectively
  (closes #7)
- Set displayName on all forwarded components for readable React DevTools
- Added tests: Button default type='button', Button ref forwarding,
  Input ref forwarding (7/7 tests passing)
@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 5efa38ff-5e31-46d7-9164-a690d404e00c


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Mona-i
Mona-i merged commit f97072a into lumio-network:main Sep 10, 2026
2 checks passed
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.

feat(ui): forward refs on Button, Input, and Card fix(ui): default Button to type="button" to avoid accidental form submits

2 participants