Skip to content

📦 refactor(button): latest shadcn/ui button styling#428

Merged
mikij merged 1 commit intomasterfrom
refactor/button
Feb 13, 2026
Merged

📦 refactor(button): latest shadcn/ui button styling#428
mikij merged 1 commit intomasterfrom
refactor/button

Conversation

@mikij
Copy link
Contributor

@mikij mikij commented Feb 12, 2026

What was done? 📝

Refactored button variants to use latest shadcn/ui variants

Screenshots or GIFs 📸

|-----Figma-----|
|-----Implementation-----|

Link to Issue 🔗

closes #425

Type of change 🏗

  • New feature (non-breaking change that adds functionality)
  • Bug fix (non-breaking change that fixes an issue)
  • Refactor (non-breaking change that improves the code or technical debt)
  • Chore (none of the above, such as upgrading libraries)

Breaking change 🚨

visual changes

Checklist 🧐

  • Tested on Chrome
  • Tested on Safari
  • Tested on Firefox
  • No errors in the console

Summary by CodeRabbit

  • Style

    • Expanded and refined button styling: new size tokens (xs, icon, icon-*, sm, lg), updated type variants, accessibility and dark‑mode improvements; date picker size heights adjusted.
  • Documentation

    • API docs updated to show new size options and adjusted table formatting.
  • Refactor / Public API

    • Date picker now exposes its own size variant type; button and date‑picker size options expanded and exported.
  • Tests

    • Button tests migrated to Testing Library with broader coverage; alert‑dialog test expectation updated for OK button styling.

@mikij mikij requested review from Luizgomess, ribeiromatheuss and srizzon and removed request for Luizgomess and ribeiromatheuss February 12, 2026 16:55
@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Button variants and tests were overhauled (new size/type tokens and Testing Library tests), an alert-dialog test expectation was adjusted, and date-picker variants/types were exported with absolute imports and standalone: true removed from its component metadata.

Changes

Cohort / File(s) Summary
Button tests
libs/zard/src/lib/shared/components/button/button.component.spec.ts
Replaced TestBed-based specs with Testing Library (render/screen), reorganized suites, and added extensive assertions covering rendering, disabled/loading/full-width states, size/type/shape variants, and icon-only detection.
Button variants & docs
libs/zard/src/lib/shared/components/button/button.variants.ts, libs/zard/src/lib/shared/components/button/doc/api.md
Reworked baseline utility classes and accessibility tokens; expanded zType variants and added new zSize tokens (xs, icon, icon-*, etc.). API docs updated to list new zSize options.
Alert dialog test
libs/zard/src/lib/shared/components/alert-dialog/alert-dialog.spec.ts
Adjusted expected destructive button class from bg-destructive to bg-destructive/10 in test assertion.
Date-picker component & variants
libs/zard/src/lib/shared/components/date-picker/date-picker.component.ts, libs/zard/src/lib/shared/components/date-picker/date-picker.variants.ts
Switched to absolute imports, exported datePickerVariants, added xs size and new ZardDatePickerSizeVariants type, changed zSize input type, and removed standalone: true from component metadata.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • srizzon
  • Luizgomess
  • ribeiromatheuss

Poem

🔘 Buttons reshaped with tokens bright and new,
Tests now render clean and check each view,
Date picker sizes added, types aligned,
A tiny alert tweak snugly redefined,
✨ Components tuned — a tidy code debut.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly references the main change: refactoring button variants to use latest shadcn/ui styling, matching the PR's primary objective.
Description check ✅ Passed The description covers the main change, links to issue #425, specifies the refactor type, and acknowledges visual breaking changes, though screenshots/GIFs sections lack content.
Linked Issues check ✅ Passed The PR removes button animations and size-change behavior by updating variants to match shadcn/ui styling [#425], addressing animation artifacts and providing animation control.
Out of Scope Changes check ✅ Passed All changes align with the refactoring scope: button variants, tests, documentation, and related component updates (date-picker size variants) are within scope for button styling updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/button

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
libs/zard/src/lib/shared/components/date-picker/date-picker.component.ts (3)

48-48: ⚠️ Potential issue | 🟠 Major

aria-expanded is hardcoded to false — accessibility bug.

This attribute never reflects the actual popover state. Screen readers will always report the popover as collapsed, even when it's open. Since the component already tracks visibility via onPopoverVisibilityChange, wire a signal to toggle this properly.

♿ Proposed fix

Add a signal to track popover visibility and bind it:

 export class ZardDatePickerComponent implements ControlValueAccessor {
   private readonly datePipe = inject(DatePipe);
+  private readonly popoverOpen = signal(false);

   ...

-      [attr.aria-expanded]="false"
+      [attr.aria-expanded]="popoverOpen()"

   ...

   protected onPopoverVisibilityChange(visible: boolean): void {
+    this.popoverOpen.set(visible);
     if (visible) {

You'll need to add signal to the @angular/core import.


149-157: 🧹 Nitpick | 🔵 Trivial

Bare setTimeout without a delay — consider documenting intent.

The setTimeout(() => { ... }) with no delay is a common Angular trick to defer execution to the next macrotask (after the popover DOM renders). It works, but a brief inline comment explaining why it's deferred would help future readers. Minor nit.


38-40: ⚠️ Potential issue | 🔴 Critical

Address TypeScript type mismatch: ZardDatePickerSizeVariants cannot be assigned to button's ZardButtonSizeVariants input.

The date-picker's zSize() is typed as ZardDatePickerSizeVariants ('sm' | 'default' | 'lg'), but the button's [zSize] input expects ZardButtonSizeVariants ('default' | 'xs' | 'sm' | 'lg' | 'icon' | 'icon-xs' | 'icon-sm' | 'icon-lg'). Although the values are a logical subset, TypeScript treats these as distinct types extracted from separate CVA definitions and will reject the assignment. Either cast the value with as ZardButtonSizeVariants or unify the type definitions to allow direct assignment.

🤖 Fix all issues with AI agents
In `@libs/zard/src/lib/shared/components/button/button.component.spec.ts`:
- Around line 219-222: The test currently asserts Tailwind pseudo-state classes
directly via expect(screen.getByRole('button')).toHaveClass('hover:bg-muted',
'hover:text-foreground'), which can be brittle if compiled output changes;
update the assertions to robustly verify the presence of those literal class
tokens (e.g., assert button.className or button.classList contains
'hover:bg-muted' and 'hover:text-foreground') and do the same for the `link`
type test so the checks rely on token containment rather than exact class
matching.
- Around line 40-68: The test for "does not render loading icon when zLoading is
false" is missing ZardIconComponent in its imports while the other loading tests
include it; update that test's render call so its imports array includes both
ZardButtonComponent and ZardIconComponent (keeping imports consistent across the
describe('loading state') block) to ensure ZardIconComponent is available for
the component under test when checking zLoading behavior.
- Around line 1-2: The spec currently imports and uses Testing Library helpers
(render, screen, waitFor) instead of Angular TestBed/ComponentFixture; refactor
the test to follow the project's TestBed standard by replacing
render/screen/waitFor usage with Angular Testing Utilities: set up
TestBed.configureTestingModule(...) including declarations/providers used by
ButtonComponent, create a ComponentFixture<ButtonComponent> via
TestBed.createComponent(ButtonComponent), call fixture.detectChanges(), and
replace screen queries with fixture.debugElement/nativeElement queries and async
waits with fixture.whenStable() or waitForAsync; update imports to remove
'@testing-library/angular' and '@testing-library/jest-dom' and import TestBed,
ComponentFixture, waitForAsync (or async) from '@angular/core/testing' and the
ButtonComponent symbol.

In `@libs/zard/src/lib/shared/components/button/button.variants.ts`:
- Line 12: The default variant in button.variants.ts currently uses the
`[a]:hover:` prefix which limits the hover style to anchor elements; update the
`default` variant's class string (the `default` key in the variants object) to
replace `[a]:hover:bg-primary/80` with `hover:bg-primary/80` so the hover effect
applies to all button types (`<a z-button>`, `<button z-button>`, `<z-button>`),
matching the other variants like `destructive`, `outline`, `secondary`, `ghost`,
and `link`.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@libs/zard/src/lib/shared/components/date-picker/date-picker.component.ts`:
- Around line 94-96: The zSize input (readonly zSize =
input<ZardDatePickerSizeVariants>('default')) currently limits allowed sizes
compared to the wrapped button's ZardButtonTypeVariants, causing an arbitrary
restriction; fix by updating the ZardDatePickerSizeVariants type to include the
full set of button size variants (e.g., add
'xs','icon','icon-xs','icon-sm','icon-lg' to the union) and ensure the input
default stays valid, or alternatively add a concise comment above readonly zSize
explaining why the date picker intentionally restricts sizes and list the
supported variants so consumers understand the constraint; reference
ZardDatePickerSizeVariants and zSize in date-picker.component.ts when making
this change.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@libs/zard/src/lib/shared/components/button/button.variants.ts`:
- Around line 5-8: The buttonVariants string uses "transition-all" which causes
unwanted animations; update the variant definition in buttonVariants (inside the
mergeClasses call) to replace "transition-all" with "transition-colors" so
transitions are limited to color changes and match shadcn/ui behavior. Ensure
the change is made where the class list is composed (the argument to
mergeClasses in button.variants.ts) and keep the rest of the class string
intact.

In `@libs/zard/src/lib/shared/components/date-picker/date-picker.component.ts`:
- Around line 26-31: HEIGHT_BY_SIZE currently types its keys as
Record<NonNullable<ZardDatePickerSizeVariants>, string> but
ZardDatePickerSizeVariants is already NonNullable, so remove the redundant
NonNullable wrapper; change the declaration to use
Record<ZardDatePickerSizeVariants, string> and keep the same entries (xs, sm,
default, lg) so references to HEIGHT_BY_SIZE and the ZardDatePickerSizeVariants
type remain correct.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
libs/zard/src/lib/shared/components/button/button.variants.ts (1)

46-51: 🧹 Nitpick | 🔵 Trivial

zLoading and zDisabled apply identical classes — consider sharing a constant.

Both variants resolve to opacity-50 + pointer-events-none (just reordered). If the intent is for them to always match, extracting a shared const disabledClasses = 'pointer-events-none opacity-50' reduces drift risk. If they're expected to diverge later, this is fine as-is.

♻️ Optional: extract shared disabled/loading classes
+const inactiveClasses = 'pointer-events-none opacity-50';
+
 export const buttonVariants = cva(
   ...
       zLoading: {
-        true: 'opacity-50 pointer-events-none',
+        true: inactiveClasses,
       },
       zDisabled: {
-        true: 'pointer-events-none opacity-50',
+        true: inactiveClasses,
       },
🤖 Fix all issues with AI agents
In `@libs/zard/src/lib/shared/components/date-picker/date-picker.component.ts`:
- Around line 26-31: Add a brief explanatory comment above the HEIGHT_BY_SIZE
constant describing that these heights intentionally override the button size
variants (e.g., default: h-9 vs button h-8, lg: h-11 vs button h-9) to
accommodate the date-picker UI, and note that mergeClasses (tailwind-merge) is
used to resolve class conflicts; reference HEIGHT_BY_SIZE,
ZardDatePickerSizeVariants, and mergeClasses so future contributors understand
the deliberate size discrepancy and don’t revert it.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
libs/zard/src/lib/shared/components/button/button.variants.ts (1)

46-51: 🧹 Nitpick | 🔵 Trivial

Inconsistent class ordering between zLoading and zDisabled.

Both variants apply the same two classes but in reversed order. While functionally equivalent (Tailwind processes them independently), aligning the order improves readability and signals they're intentionally identical.

Suggested fix
       zLoading: {
-        true: 'opacity-50 pointer-events-none',
+        true: 'pointer-events-none opacity-50',
       },

@mikij mikij merged commit daa6afb into master Feb 13, 2026
5 checks passed
@mikij mikij deleted the refactor/button branch February 13, 2026 20:14
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.

[Feature Request] - Remove or Disable Button animations

2 participants