Skip to content

feat(vue/button): responsive touch targets + as prop#441

Merged
Shooksie merged 1 commit intomainfrom
feat/vue-button-responsive-sizing-as-prop-20260423
Apr 23, 2026
Merged

feat(vue/button): responsive touch targets + as prop#441
Shooksie merged 1 commit intomainfrom
feat/vue-button-responsive-sizing-as-prop-20260423

Conversation

@Shooksie
Copy link
Copy Markdown
Contributor

Why

The design-system Vue Button.vue had fixed heights (h-9/h-10) with no mobile responsive sizing, failing WCAG 2.5.8 minimum touch target requirements on phones. It also lacked an as prop, forcing callers to hand-roll full class strings for link/router use cases. Additionally, rounded-[--la-radius] was invalid CSS (bare custom property outside var()) rendering as no border-radius.

What

  • src/vue/components/Button.vue
    • Responsive heights: smh-11 md:h-9, mdh-12 md:h-10, plus min-h-[44px] on mobile (resets with md:min-h-0)
    • lg keeps h-12 with min-h-[44px] (already desktop-sized)
    • iconh-11 w-11 md:h-10 md:w-10 min-h-[44px] min-w-[44px] md:min-h-0 md:min-w-0
    • as prop (default: "button") — polymorphic rendering; resolves Vue components (NuxtLink, RouterLink) via resolveComponent(); native HTML tags pass through directly; type + disabled only bind on <button>, aria-disabled used otherwise
    • rounded-[--la-radius]rounded-[var(--la-radius)] (CSS fix)
    • outline variant gains text-foreground (matches app-level copies)

Matches the pattern already shipped in:

  • launchapp-nuxt app-level Button + PR #573 (as prop)
  • launchapp-react-router flagship ui-kit/Button.tsx

Verification

  • pnpm build passes (ESM + CJS + DTS)
  • pnpm lint passes (0 errors, warnings unchanged)
  • pnpm test passes (283/283)

- h-11/md:h-9 for sm, h-12/md:h-10 for md, min-h-[44px] on all
  sizes — matches WCAG 2.5.8 target size on mobile
- icon size adds min-w-[44px] touch target, resets on md+
- as prop (default: "button") for polymorphic rendering — resolves
  Vue components (NuxtLink, RouterLink) via resolveComponent();
  native HTML elements pass through directly; type + disabled only
  bind on <button>, aria-disabled used otherwise
- rounded-[--la-radius] → rounded-[var(--la-radius)] (invalid CSS
  bare custom property — must wrap in var())
- outline variant gains text-foreground to match app-level copies
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
design-system Ready Ready Preview, Comment Apr 23, 2026 9:10am

Request Review

@Shooksie
Copy link
Copy Markdown
Contributor Author

PR Review — AO PR-Reviewer ✓ APPROVED FOR MERGE

Scope: CLEAN — responsive touch targets + as prop + CSS fix + outline text-foreground. No scope creep.

Critical pass: No findings. No SQL, no race conditions, no LLM boundaries, no shell injection.

Token compliance (§5b): Clean.

  • rounded-[--la-radius]rounded-[var(--la-radius)] — real CSS bug fixed ✓
  • All color classes use semantic tokens (bg-primary, text-foreground, border-input, etc.) — zero hardcoded hex ✓
  • min-h-[44px] is a WCAG 2.5.8 sizing constraint, not a color value — exempt from §5b ✓

Informational (non-blocking):

  1. resolveComponent inside computed() — outside Vue's documented call context (should be synchronous in setup()). Works in all current Vue 3.x. Low risk, worth migrating if SSR edge cases appear.
  2. aria-disabled on non-button elements doesn't suppress click events — disabled:pointer-events-none only fires on native :disabled. Known trade-off for polymorphic buttons (same as Radix/shadcn). Worth a JSDoc note so callers know to add @click.prevent if they need hard-disabled on div/span.

CI: All green (Quality Checks ✓, Vercel ✓, Chromatic ✓).

Merging.

@Shooksie Shooksie merged commit 6e1d073 into main Apr 23, 2026
4 checks passed
@Shooksie Shooksie deleted the feat/vue-button-responsive-sizing-as-prop-20260423 branch April 23, 2026 10:08
@Shooksie
Copy link
Copy Markdown
Contributor Author

rework-pr phase: no rework needed. PR was approved with zero blocking findings and has already been merged. The two informational notes (resolveComponent call context, aria-disabled on non-button) were explicitly marked non-blocking by the reviewer.

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.

1 participant