Run the CLI
Use the CLI to add carousel to your project.
npx zard-cli@latest add carouselMajor infrastructure improvements this month! We focused on developer experience with a new provider system, CLI enhancements with our own private registry, and streamlined dark-mode setup.
New provider function for streamlined app configuration. Add event manager plugins and other Zard utilities with a single function call in your app.config.ts.
provideZard()The CLI now uses our own private registry instead of fetching from GitHub. This brings significant performance improvements, better version control, and more reliable component installations.
Adding dark-mode support to your project is now as simple as running a single CLI command. It automatically configures everything you need.
npx zard-cli@latest add dark-modeMajor updates this month with new interactive components including Carousel, Button Group, Input Group, and Kbd components. Enhanced user experience with better form controls and keyboard navigation support.
Use the CLI to add carousel to your project.
npx zard-cli@latest add carouselpnpm dlx zard-cli@latest add carouselyarn dlx zard-cli@latest add carouselbunx zard-cli@latest add carouselA slideshow component for cycling through elements with support for mouse drag, touch swipe, and automatic playback.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ZardCardComponent } from '../../card';
import { ZardCarouselImports } from '../carousel.imports';
@Component({
imports: [ZardCarouselImports, ZardCardComponent],
template: `
<div class="mx-auto w-3/4 max-w-md">
<z-carousel>
<z-carousel-content>
@for (slide of slides; track slide) {
<z-carousel-item>
<z-card>
<div class="flex h-25 items-center justify-center text-4xl font-semibold md:h-50">
{{ slide }}
</div>
</z-card>
</z-carousel-item>
}
</z-carousel-content>
</z-carousel>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoCarouselDefaultComponent {
protected slides = ['1', '2', '3', '4', '5'];
}
Use the CLI to add kbd to your project.
npx zard-cli@latest add kbdpnpm dlx zard-cli@latest add kbdyarn dlx zard-cli@latest add kbdbunx zard-cli@latest add kbdDisplay keyboard keys and shortcuts in a visually consistent way.
import { Component } from '@angular/core';
import { ZardButtonComponent } from '../../button/button.component';
import { ZardKbdComponent } from '../kbd.component';
@Component({
selector: 'z-demo-kbd-default',
imports: [ZardKbdComponent, ZardButtonComponent],
standalone: true,
template: `
<div class="flex flex-col items-center justify-center gap-4">
<div class="flex items-center gap-2">
<z-kbd>Esc</z-kbd>
<z-kbd>⌘</z-kbd>
<z-kbd>Ctrl</z-kbd>
</div>
<button type="submit" z-button zType="outline">
Submit
<z-kbd class="ml-2">Enter</z-kbd>
</button>
</div>
`,
})
export class ZardDemoKbdDefaultComponent {}
Breaking changes with icons migration from lucide-static to lucide-angular for better performance. New layout components including Sheet and Empty state component for better UX.
Use the CLI to add sheet to your project.
npx zard-cli@latest add sheetpnpm dlx zard-cli@latest add sheetyarn dlx zard-cli@latest add sheetbunx zard-cli@latest add sheetA versatile sheet component for side panels and overlays with customizable positioning and smooth transitions.
import { ChangeDetectionStrategy, Component, inject, type AfterViewInit } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ZardButtonComponent } from '@/shared/components/button';
import { ZardInputDirective } from '@/shared/components/input';
import { ZardSheetImports } from '@/shared/components/sheet/sheet.imports';
import { Z_SHEET_DATA, ZardSheetService } from '@/shared/components/sheet/sheet.service';
interface iSheetData {
name: string;
username: string;
}
@Component({
selector: 'zard-demo-sheet-basic',
imports: [FormsModule, ReactiveFormsModule, ZardInputDirective],
template: `
<form [formGroup]="form" class="grid flex-1 auto-rows-min gap-6 px-4">
<div class="grid gap-3">
<label
for="name"
class="flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50"
>
Name
</label>
<input
z-input
formControlName="name"
class="file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
/>
</div>
<div class="grid gap-3">
<label
for="username"
class="flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50"
>
Username
</label>
<input
z-input
formControlName="username"
class="file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
/>
</div>
</form>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
exportAs: 'zardDemoSheetBasic',
})
export class ZardDemoSheetBasicInputComponent implements AfterViewInit {
private zData: iSheetData = inject(Z_SHEET_DATA);
form = new FormGroup({
name: new FormControl(''),
username: new FormControl(''),
});
ngAfterViewInit(): void {
if (this.zData) {
this.form.patchValue(this.zData);
}
}
}
@Component({
imports: [ZardButtonComponent, ZardSheetImports],
template: `
<button type="button" z-button zType="outline" (click)="openSheet()">Edit profile</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSheetBasicComponent {
private sheetService = inject(ZardSheetService);
openSheet() {
this.sheetService.create({
zTitle: 'Edit profile',
zDescription: `Make changes to your profile here. Click save when you're done.`,
zContent: ZardDemoSheetBasicInputComponent,
zData: {
name: 'Matheus Ribeiro',
username: '@ribeiromatheus.dev',
},
zOkText: 'Save changes',
zOnOk: instance => {
console.log('Form submitted:', instance.form.value);
},
});
}
}
Use the CLI to add empty to your project.
npx zard-cli@latest add emptypnpm dlx zard-cli@latest add emptyyarn dlx zard-cli@latest add emptybunx zard-cli@latest add emptyClean empty state component for "no data" scenarios with customizable messages and icons.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ZardButtonComponent } from '../../button/button.component';
import { ZardIconComponent } from '../../icon/icon.component';
import { ZardEmptyComponent } from '../empty.component';
@Component({
selector: 'z-demo-empty-default',
imports: [ZardButtonComponent, ZardEmptyComponent, ZardIconComponent],
template: `
<z-empty
zIcon="folder-code"
zTitle="No Projects Yet"
zDescription="You haven't created any projects yet. Get started by creating your first project."
[zActions]="[actionPrimary, actionSecondary]"
>
<ng-template #actionPrimary>
<button type="button" z-button>Create Project</button>
</ng-template>
<ng-template #actionSecondary>
<button type="button" z-button zType="outline">Import Project</button>
</ng-template>
<button type="button" z-button zType="link" zSize="sm" class="text-muted-foreground">
Learn More
<z-icon zType="arrow-up-right" />
</button>
</z-empty>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoEmptyDefaultComponent {}
Focus on loading and feedback components this month. New Progress, Skeleton, and Loader components for better perceived performance and user feedback during async operations.
Use the CLI to add progress-bar to your project.
npx zard-cli@latest add progress-barpnpm dlx zard-cli@latest add progress-baryarn dlx zard-cli@latest add progress-barbunx zard-cli@latest add progress-barVisual progress indicator with customizable variants for tracking task completion and loading states.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ZardProgressBarComponent } from '../progress-bar.component';
@Component({
selector: 'z-demo-progress-bar-basic',
imports: [ZardProgressBarComponent],
template: `
<z-progress-bar [progress]="50" />
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoProgressBarBasicComponent {}
Use the CLI to add skeleton to your project.
npx zard-cli@latest add skeletonpnpm dlx zard-cli@latest add skeletonyarn dlx zard-cli@latest add skeletonbunx zard-cli@latest add skeletonLoading placeholder component for better perceived performance during content loading with pulse animation.
import { Component } from '@angular/core';
import { ZardSkeletonComponent } from '../skeleton.component';
@Component({
selector: 'z-demo-skeleton-default',
imports: [ZardSkeletonComponent],
standalone: true,
template: `
<div class="flex items-center space-x-4">
<z-skeleton class="size-12 rounded-full" />
<div class="space-y-2">
<z-skeleton class="h-4 w-[250px]" />
<z-skeleton class="h-4 w-[200px]" />
</div>
</div>
`,
})
export class ZardDemoSkeletonDefaultComponent {}
Use the CLI to add loader to your project.
npx zard-cli@latest add loaderpnpm dlx zard-cli@latest add loaderyarn dlx zard-cli@latest add loaderbunx zard-cli@latest add loaderAnimated loading spinner with multiple size variants for indicating async operations in progress.
import { Component } from '@angular/core';
import { ZardLoaderComponent } from '../loader.component';
@Component({
selector: 'z-demo-loader-default',
imports: [ZardLoaderComponent],
standalone: true,
template: `
<z-loader />
`,
})
export class ZardDemoLoaderDefaultComponent {}
Enhanced navigation and display components. New Avatar component with fallback support, Divider for content separation, and Breadcrumb for hierarchical navigation.
Use the CLI to add avatar to your project.
npx zard-cli@latest add avatarpnpm dlx zard-cli@latest add avataryarn dlx zard-cli@latest add avatarbunx zard-cli@latest add avatarUser profile image component with automatic fallback to initials and multiple size variants.



import { Component } from '@angular/core';
import { ZardAvatarGroupComponent } from '../avatar-group.component';
import { ZardAvatarComponent } from '../avatar.component';
@Component({
selector: 'z-demo-avatar-basic',
imports: [ZardAvatarComponent, ZardAvatarGroupComponent],
standalone: true,
template: `
<z-avatar zSrc="/images/avatar/imgs/avatar_image.jpg" zFallback="ZA" [zSize]="32" />
<z-avatar zSrc="error-image.png" zFallback="ZA" zSize="sm" />
<z-avatar-group>
<z-avatar zSrc="/images/avatar/imgs/avatar_image.jpg" zFallback="JD" zSize="sm" />
<z-avatar zSrc="https://github.com/srizzon.png" zFallback="SA" zSize="sm" />
<z-avatar zSrc="https://github.com/Luizgomess.png" zFallback="LU" zSize="sm" />
</z-avatar-group>
`,
})
export class ZardDemoAvatarBasicComponent {}
Use the CLI to add divider to your project.
npx zard-cli@latest add dividerpnpm dlx zard-cli@latest add divideryarn dlx zard-cli@latest add dividerbunx zard-cli@latest add dividerVisual divider component for separating content sections with horizontal and vertical orientations.
Before divider
After divider
import { Component } from '@angular/core';
import { ZardDividerComponent } from '../divider.component';
@Component({
selector: 'z-demo-divider-default',
imports: [ZardDividerComponent],
standalone: true,
template: `
<div class="flex flex-col">
<p>Before divider</p>
<z-divider />
<p>After divider</p>
</div>
`,
})
export class ZardDemoDividerDefaultComponent {}
Use the CLI to add breadcrumb to your project.
npx zard-cli@latest add breadcrumbpnpm dlx zard-cli@latest add breadcrumbyarn dlx zard-cli@latest add breadcrumbbunx zard-cli@latest add breadcrumbNavigation breadcrumb trail showing the current page location within a hierarchical structure.
import { Component } from '@angular/core';
import { ZardIconComponent } from '../../icon/icon.component';
import { ZardBreadcrumbImports } from '../breadcrumb.imports';
@Component({
selector: 'z-demo-breadcrumb-default',
imports: [ZardBreadcrumbImports, ZardIconComponent],
standalone: true,
template: `
<z-breadcrumb zWrap="wrap" zAlign="start">
<z-breadcrumb-item [routerLink]="['/']">
<z-icon zType="house" />
Home
</z-breadcrumb-item>
<z-breadcrumb-item [routerLink]="['/docs/components']">Components</z-breadcrumb-item>
<z-breadcrumb-item>Breadcrumb</z-breadcrumb-item>
</z-breadcrumb>
`,
})
export class ZardDemoBreadcrumbDefaultComponent {}
Major release of navigation and content organization components. New Tabs for multi-view interfaces, Accordion for collapsible content, and Tooltip for contextual information. Theming system improvements with new color palettes.
Use the CLI to add tabs to your project.
npx zard-cli@latest add tabspnpm dlx zard-cli@latest add tabsyarn dlx zard-cli@latest add tabsbunx zard-cli@latest add tabsTabbed interface component for organizing content into separate views with smooth transitions and keyboard navigation.
Is the default tab component
Content of the second tab
Content of the third tab
Content of the fourth tab
Content of the fifth tab
Content of the sixth tab
import { Component } from '@angular/core';
import { ZardTabComponent, ZardTabGroupComponent } from '../tabs.component';
@Component({
selector: 'z-demo-tabs-default',
imports: [ZardTabComponent, ZardTabGroupComponent],
standalone: true,
template: `
<div class="h-[300px] w-full">
<z-tab-group>
<z-tab label="First">
<p>Is the default tab component</p>
</z-tab>
<z-tab label="Second">
<p>Content of the second tab</p>
</z-tab>
<z-tab label="Third">
<p>Content of the third tab</p>
</z-tab>
<z-tab label="Fourth">
<p>Content of the fourth tab</p>
</z-tab>
<z-tab label="Fifth">
<p>Content of the fifth tab</p>
</z-tab>
<z-tab label="Sixth">
<p>Content of the sixth tab</p>
</z-tab>
</z-tab-group>
</div>
`,
})
export class ZardDemoTabsDefaultComponent {}
Use the CLI to add accordion to your project.
npx zard-cli@latest add accordionpnpm dlx zard-cli@latest add accordionyarn dlx zard-cli@latest add accordionbunx zard-cli@latest add accordionCollapsible content panels for organizing information in a compact space with expand/collapse animations.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ZardAccordionImports } from '@/shared/components/accordion/accordion.imports';
@Component({
selector: 'z-demo-accordion-basic',
imports: [ZardAccordionImports],
template: `
<z-accordion zDefaultValue="item-2">
<z-accordion-item zValue="item-1" zTitle="A Study in Scarlet">
The first case of Sherlock Holmes and Dr. Watson. They investigate a murder in London, which leads to a
backstory involving Mormons in the U.S. Introduces Holmes’s deductive method.
</z-accordion-item>
<z-accordion-item zValue="item-2" zTitle="The Sign of Four" zDescription="Sir Arthur Conan Doyle">
The first case of Sherlock Holmes and Dr. Watson. They investigate a murder in London, which leads to a
backstory involving Mormons in the U.S. Introduces Holmes’s deductive method.
</z-accordion-item>
<z-accordion-item zValue="item-3" zTitle="The Hound of the Baskervilles">
Holmes and Watson investigate the legend of a demonic hound haunting the Baskerville family. Set in the eerie
Dartmoor moorlands, the story involves betrayal and greed.
</z-accordion-item>
</z-accordion>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoAccordionBasicComponent {}
Use the CLI to add tooltip to your project.
npx zard-cli@latest add tooltippnpm dlx zard-cli@latest add tooltipyarn dlx zard-cli@latest add tooltipbunx zard-cli@latest add tooltipContextual information overlay displayed on hover with customizable positioning and delay settings.
import { Component } from '@angular/core';
import { ZardTooltipImports } from '@/shared/components/tooltip/tooltip.imports';
import { ZardButtonComponent } from '../../button/button.component';
@Component({
selector: 'z-demo-tooltip-hover',
imports: [ZardButtonComponent, ZardTooltipImports],
template: `
<button type="button" z-button zType="outline" zTooltip="Tooltip content">Hover</button>
`,
})
export class ZardDemoTooltipHoverComponent {}
Overlay components release! New Dialog, Popover, Alert Dialog, and Dropdown Menu components. CVA integration for type-safe styling variants across all components.
Use the CLI to add dialog to your project.
npx zard-cli@latest add dialogpnpm dlx zard-cli@latest add dialogyarn dlx zard-cli@latest add dialogbunx zard-cli@latest add dialogModal dialog component for displaying important content that requires user attention with backdrop overlay.
import { ChangeDetectionStrategy, Component, inject, type AfterViewInit } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ZardButtonComponent } from '../../button/button.component';
import { ZardInputDirective } from '../../input/input.directive';
import { ZardSelectItemComponent } from '../../select/select-item.component';
import { ZardSelectComponent } from '../../select/select.component';
import { ZardDialogModule } from '../dialog.component';
import { Z_MODAL_DATA, ZardDialogService } from '../dialog.service';
interface iDialogData {
name: string;
username: string;
}
@Component({
selector: 'zard-demo-dialog-basic',
imports: [FormsModule, ReactiveFormsModule, ZardInputDirective, ZardSelectComponent, ZardSelectItemComponent],
template: `
<form [formGroup]="form" class="grid gap-4">
<div class="grid gap-3">
<label
for="name"
class="flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50"
>
Name
</label>
<input z-input formControlName="name" />
</div>
<div class="grid gap-3">
<label
for="username"
class="flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50"
>
Username
</label>
<input z-input formControlName="username" />
</div>
<div class="grid gap-3">
<label
for="region"
class="flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50"
>
Region
</label>
<z-select formControlName="region">
<z-select-item zValue="africa">Africa</z-select-item>
<z-select-item zValue="america">America</z-select-item>
<z-select-item zValue="asia">Asia</z-select-item>
<z-select-item zValue="australia">Australia</z-select-item>
<z-select-item zValue="europe">Europe</z-select-item>
</z-select>
</div>
</form>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
exportAs: 'zardDemoDialogBasic',
})
export class ZardDemoDialogBasicInputComponent implements AfterViewInit {
private zData: iDialogData = inject(Z_MODAL_DATA);
form = new FormGroup({
name: new FormControl('Pedro Duarte'),
username: new FormControl('@peduarte'),
region: new FormControl(''),
});
ngAfterViewInit(): void {
if (this.zData) {
this.form.patchValue(this.zData);
}
}
}
@Component({
imports: [ZardButtonComponent, ZardDialogModule],
template: `
<button type="button" z-button zType="outline" (click)="openDialog()">Edit profile</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoDialogBasicComponent {
private dialogService = inject(ZardDialogService);
openDialog() {
this.dialogService.create({
zTitle: 'Edit Profile',
zDescription: `Make changes to your profile here. Click save when you're done.`,
zContent: ZardDemoDialogBasicInputComponent,
zData: {
name: 'Samuel Rizzon',
username: '@samuelrizzondev',
region: 'america',
} as iDialogData,
zOkText: 'Save changes',
zOnOk: instance => {
console.log('Form submitted:', instance.form.value);
},
zWidth: '425px',
});
}
}
Use the CLI to add popover to your project.
npx zard-cli@latest add popoverpnpm dlx zard-cli@latest add popoveryarn dlx zard-cli@latest add popoverbunx zard-cli@latest add popoverFloating content container that appears on trigger with customizable positioning and close behavior.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ZardButtonComponent } from '../../button/button.component';
import { ZardPopoverComponent, ZardPopoverDirective } from '../popover.component';
@Component({
selector: 'z-popover-default-demo',
imports: [ZardButtonComponent, ZardPopoverComponent, ZardPopoverDirective],
standalone: true,
template: `
<button type="button" z-button zPopover [zContent]="popoverContent" zType="outline">Open popover</button>
<ng-template #popoverContent>
<z-popover>
<div class="space-y-2">
<h4 class="leading-none font-medium">Dimensions</h4>
<p class="text-muted-foreground text-sm">Set the dimensions for the layer.</p>
</div>
</z-popover>
</ng-template>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoPopoverDefaultComponent {}
Use the CLI to add alert-dialog to your project.
npx zard-cli@latest add alert-dialogpnpm dlx zard-cli@latest add alert-dialogyarn dlx zard-cli@latest add alert-dialogbunx zard-cli@latest add alert-dialogConfirmation dialog for critical actions requiring explicit user confirmation with cancel and confirm options.
import { Component, inject } from '@angular/core';
import { ZardButtonComponent } from '../../button/button.component';
import { ZardAlertDialogService } from '../alert-dialog.service';
@Component({
selector: 'zard-demo-alert-dialog-default',
imports: [ZardButtonComponent],
standalone: true,
template: `
<button z-button zType="outline" (click)="showDialog()">Show Dialog</button>
`,
})
export class ZardDemoAlertDialogDefaultComponent {
private alertDialogService = inject(ZardAlertDialogService);
showDialog() {
this.alertDialogService.confirm({
zTitle: 'Are you absolutely sure?',
zDescription:
'This action cannot be undone. This will permanently delete your account and remove your data from our servers.',
zOkText: 'Continue',
zCancelText: 'Cancel',
});
}
}
Use the CLI to add dropdown to your project.
npx zard-cli@latest add dropdownpnpm dlx zard-cli@latest add dropdownyarn dlx zard-cli@latest add dropdownbunx zard-cli@latest add dropdownContext menu with hierarchical actions, keyboard navigation, and support for nested submenus.
import { Component } from '@angular/core';
import { ZardButtonComponent } from '@/shared/components/button';
import { ZardDividerComponent } from '@/shared/components/divider';
import { ZardDropdownImports } from '@/shared/components/dropdown/dropdown.imports';
import { ZardMenuImports } from '@/shared/components/menu';
@Component({
selector: 'z-dropdown-demo',
imports: [ZardDropdownImports, ZardButtonComponent, ZardDividerComponent, ZardMenuImports],
template: `
<button type="button" z-button zType="outline" z-dropdown [zDropdownMenu]="menu">Open</button>
<z-dropdown-menu-content #menu="zDropdownMenuContent" class="w-56">
<z-menu-label>My Account</z-menu-label>
<z-dropdown-menu-item (click)="onProfile()">
Profile
<z-menu-shortcut>⇧⌘P</z-menu-shortcut>
</z-dropdown-menu-item>
<z-dropdown-menu-item (click)="onBilling()">
Billing
<z-menu-shortcut>⌘B</z-menu-shortcut>
</z-dropdown-menu-item>
<z-dropdown-menu-item (click)="onSettings()">
Settings
<z-menu-shortcut>⌘S</z-menu-shortcut>
</z-dropdown-menu-item>
<z-dropdown-menu-item (click)="onKeyboardShortcuts()">
Keyboard shortcuts
<z-menu-shortcut>⌘K</z-menu-shortcut>
</z-dropdown-menu-item>
<z-divider zSpacing="sm" class="-mx-1" />
<z-dropdown-menu-item (click)="onTeam()">Team</z-dropdown-menu-item>
<z-dropdown-menu-item (click)="onNewTeam()">
New Team
<z-menu-shortcut>⌘+T</z-menu-shortcut>
</z-dropdown-menu-item>
<z-divider zSpacing="sm" class="-mx-1" />
<z-dropdown-menu-item (click)="onGitHub()">GitHub</z-dropdown-menu-item>
<z-dropdown-menu-item (click)="onSupport()">Support</z-dropdown-menu-item>
<z-dropdown-menu-item [disabled]="true">API</z-dropdown-menu-item>
<z-divider zSpacing="sm" class="-mx-1" />
<z-dropdown-menu-item (click)="onLogout()">
Log out
<z-menu-shortcut>⇧⌘Q</z-menu-shortcut>
</z-dropdown-menu-item>
</z-dropdown-menu-content>
`,
})
export class ZardDropdownDemoComponent {
onProfile() {
console.log('Profile clicked');
}
onBilling() {
console.log('Billing clicked');
}
onSettings() {
console.log('Settings clicked');
}
onKeyboardShortcuts() {
console.log('Keyboard shortcuts clicked');
}
onTeam() {
console.log('Team clicked');
}
onNewTeam() {
console.log('New Team clicked');
}
onGitHub() {
console.log('GitHub clicked');
}
onSupport() {
console.log('Support clicked');
}
onLogout() {
console.log('Log out clicked');
}
}
Comprehensive form controls release! New Select, Checkbox, Radio, Switch, and Slider components with full Angular Reactive Forms integration and ControlValueAccessor support.
Use the CLI to add select to your project.
npx zard-cli@latest add selectpnpm dlx zard-cli@latest add selectyarn dlx zard-cli@latest add selectbunx zard-cli@latest add selectAdvanced dropdown select with search functionality, multi-select support, and custom item rendering.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ZardBadgeComponent } from '@/shared/components/badge';
import { ZardSelectImports } from '@/shared/components/select/select.imports';
@Component({
selector: 'z-demo-select-basic',
imports: [ZardBadgeComponent, ZardSelectImports],
template: `
<div class="flex flex-col gap-4">
<span>
Selected value:
@if (selectedValue) {
<z-badge>{{ selectedValue }}</z-badge>
}
</span>
<z-select class="w-75" zPlaceholder="Select a fruit" [(zValue)]="selectedValue">
<z-select-item zValue="apple">Apple</z-select-item>
<z-select-item zValue="banana">Banana</z-select-item>
<z-select-item zValue="blueberry">Blueberry</z-select-item>
<z-select-item zValue="grapes">Grapes</z-select-item>
<z-select-item zValue="pineapple" zDisabled>Pineapple</z-select-item>
</z-select>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSelectBasicComponent {
selectedValue = '';
}
Use the CLI to add checkbox to your project.
npx zard-cli@latest add checkboxpnpm dlx zard-cli@latest add checkboxyarn dlx zard-cli@latest add checkboxbunx zard-cli@latest add checkboxCheckbox input component with indeterminate state support and full accessibility features.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ZardCheckboxComponent } from '../checkbox.component';
@Component({
selector: 'z-demo-checkbox-default',
imports: [ZardCheckboxComponent, FormsModule],
template: `
<span z-checkbox></span>
<span z-checkbox [(ngModel)]="checked">Default Checked</span>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoCheckboxDefaultComponent {
checked = true;
}
Use the CLI to add radio to your project.
npx zard-cli@latest add radiopnpm dlx zard-cli@latest add radioyarn dlx zard-cli@latest add radiobunx zard-cli@latest add radioRadio button group for mutually exclusive options with customizable layouts and orientation.
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ZardRadioComponent } from '../radio.component';
@Component({
selector: 'z-demo-radio-default',
imports: [ZardRadioComponent, FormsModule],
standalone: true,
template: `
<div class="flex flex-col gap-3">
<span z-radio name="option" [(ngModel)]="selected" value="default">Default</span>
<span z-radio name="option" [(ngModel)]="selected" value="comfortable">Comfortable</span>
<span z-radio name="option" [(ngModel)]="selected" value="compact">Compact</span>
</div>
`,
})
export class ZardDemoRadioDefaultComponent {
selected = 'default';
}
Use the CLI to add switch to your project.
npx zard-cli@latest add switchpnpm dlx zard-cli@latest add switchyarn dlx zard-cli@latest add switchbunx zard-cli@latest add switchToggle switch component for boolean settings with smooth animation transitions.
import { Component } from '@angular/core';
import { ZardSwitchComponent } from '../switch.component';
@Component({
selector: 'zard-demo-switch',
imports: [ZardSwitchComponent],
template: `
<z-switch />
`,
})
export class ZardDemoSwitchDefaultComponent {}
Use the CLI to add slider to your project.
npx zard-cli@latest add sliderpnpm dlx zard-cli@latest add slideryarn dlx zard-cli@latest add sliderbunx zard-cli@latest add sliderRange slider for numeric value selection with min/max bounds, step support, and value display.
import { Component } from '@angular/core';
import { ZardSliderComponent } from '../slider.component';
@Component({
selector: 'z-demo-slider-default',
imports: [ZardSliderComponent],
template: `
<div class="flex min-h-87.5 w-full items-center justify-center p-10">
<z-slider class="w-[60%]" zDefault="50" />
</div>
`,
})
export class ZardDemoSliderDefaultComponent {}
Form foundations and CLI launch! New Input and Form components with validation support. Official CLI tool released for easy project initialization and component installation.
Use the CLI to add input to your project.
npx zard-cli@latest add inputpnpm dlx zard-cli@latest add inputyarn dlx zard-cli@latest add inputbunx zard-cli@latest add inputText input field component with multiple variants, sizes, and built-in validation state indicators.
import { ChangeDetectionStrategy, Component, inject, type AfterViewInit } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { ZardInputDirective } from '../input.directive';
@Component({
selector: 'z-demo-input-default',
imports: [ZardInputDirective, ReactiveFormsModule],
template: `
<form [formGroup]="form" class="flex flex-col gap-3">
<input z-input placeholder="Name" formControlName="name" />
<input z-input placeholder="Disabled" formControlName="novalue" />
</form>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoInputDefaultComponent implements AfterViewInit {
private fb = inject(FormBuilder);
readonly form = this.fb.group({
name: [''],
novalue: [''],
});
ngAfterViewInit(): void {
this.form.get('novalue')?.disable();
this.form.patchValue({ name: 'John Doe' });
}
}
Use the CLI to add form to your project.
npx zard-cli@latest add formpnpm dlx zard-cli@latest add formyarn dlx zard-cli@latest add formbunx zard-cli@latest add formComplete form component with field management, validation, error handling, and submission control.
import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ZardIdDirective } from '@/shared/core';
import { ZardButtonComponent } from '../../button/button.component';
import { ZardInputDirective } from '../../input/input.directive';
import { ZardFormImports } from '../form.imports';
@Component({
selector: 'zard-demo-form-default',
imports: [FormsModule, ZardButtonComponent, ZardInputDirective, ZardFormImports, ZardIdDirective],
template: `
<form class="max-w-sm space-y-6">
<z-form-field zardId="fullName" #f="zardId">
<label z-form-label zRequired [for]="f.id()">Full Name</label>
<z-form-control>
<input
z-input
type="text"
[id]="f.id()"
placeholder="Enter your full name"
[(ngModel)]="fullName"
name="fullName"
/>
</z-form-control>
<z-form-message>This is your display name.</z-form-message>
</z-form-field>
<z-form-field zardId="email" #e="zardId">
<label z-form-label zRequired [for]="e.id()">Email</label>
<z-form-control>
<input z-input type="email" [id]="e.id()" placeholder="Enter your email" [(ngModel)]="email" name="email" />
</z-form-control>
<z-form-message>We'll never share your email with anyone else.</z-form-message>
</z-form-field>
<z-form-field zardId="bio" #b="zardId">
<label z-form-label [for]="b.id()">Bio</label>
<z-form-control>
<textarea
z-input
[id]="b.id()"
placeholder="Tell us about yourself"
rows="3"
[(ngModel)]="bio"
name="bio"
></textarea>
</z-form-control>
<z-form-message>Optional: Brief description about yourself.</z-form-message>
</z-form-field>
<button z-button zType="default" type="submit">Submit</button>
</form>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class ZardDemoFormDefaultComponent {
fullName = '';
email = '';
bio = '';
}
🎉 Initial release of ZardUI! An Angular component library built with TailwindCSS v4, featuring standalone components, signal-based reactivity, and modern Angular architecture. Core components including Button, Card, Badge, Alert, and Table.
Use the CLI to add button to your project.
npx zard-cli@latest add buttonpnpm dlx zard-cli@latest add buttonyarn dlx zard-cli@latest add buttonbunx zard-cli@latest add buttonVersatile button component with multiple variants (primary, secondary, outline, ghost), sizes, and loading states.
import { Component } from '@angular/core';
import { ZardIconComponent } from '../../icon/icon.component';
import { ZardButtonComponent } from '../button.component';
@Component({
selector: 'z-demo-button-default',
imports: [ZardButtonComponent, ZardIconComponent],
standalone: true,
template: `
<button z-button zType="outline">Button</button>
<button z-button zType="outline"><i z-icon zType="arrow-up"></i></button>
<button z-button zType="outline">
Button
<i z-icon zType="popcorn"></i>
</button>
`,
})
export class ZardDemoButtonDefaultComponent {}
Use the CLI to add card to your project.
npx zard-cli@latest add cardpnpm dlx zard-cli@latest add cardyarn dlx zard-cli@latest add cardbunx zard-cli@latest add cardContainer component for grouping related content with optional header, footer, and customizable padding.
import { Component } from '@angular/core';
import { ZardButtonComponent } from '@/shared/components/button/button.component';
import { ZardCardComponent } from '@/shared/components/card/card.component';
import { ZardIdDirective } from '@/shared/core';
@Component({
selector: 'z-demo-card-default',
imports: [ZardCardComponent, ZardButtonComponent, ZardIdDirective],
template: `
<z-card
class="w-full md:w-94"
zTitle="Login to your account"
zDescription="Enter your email below to login to your account"
zAction="Sign Up"
(zActionClick)="onActionClick()"
>
<div class="space-y-4">
<div class="space-y-2" zardId="email" #e="zardId">
<label
[for]="e.id()"
class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Email
</label>
<input
[id]="e.id()"
type="email"
placeholder="m@example.com"
class="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
required
/>
</div>
<div class="space-y-2">
<div class="flex items-center" zardId="password" #p="zardId">
<label
[for]="p.id()"
class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Password
</label>
<a href="#" class="ml-auto text-sm underline-offset-4 hover:underline">Forgot your password?</a>
</div>
<input
[id]="p.id()"
type="password"
class="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
required
/>
</div>
</div>
<div card-footer class="flex w-full flex-col gap-2">
<z-button zType="default">Login</z-button>
<z-button zType="outline">Login with Google</z-button>
</div>
</z-card>
`,
})
export class ZardDemoCardDefaultComponent {
protected onActionClick(): void {
alert('Redirect to Sign Up');
}
}
Use the CLI to add badge to your project.
npx zard-cli@latest add badgepnpm dlx zard-cli@latest add badgeyarn dlx zard-cli@latest add badgebunx zard-cli@latest add badgeSmall label component for displaying status, categories, counts, or tags with various color variants.
import { Component } from '@angular/core';
import { ZardIconComponent } from '../../icon/icon.component';
import { ZardBadgeComponent } from '../badge.component';
@Component({
selector: 'z-demo-badge-default',
imports: [ZardBadgeComponent, ZardIconComponent],
standalone: true,
template: `
<div class="flex flex-col items-center gap-2">
<div class="flex w-full flex-wrap gap-2">
<z-badge>Badge</z-badge>
<z-badge zType="secondary">Secondary</z-badge>
<z-badge zType="destructive">Destructive</z-badge>
<z-badge zType="outline">Outline</z-badge>
</div>
<div class="flex w-full flex-wrap gap-2">
<z-badge zType="secondary" zShape="pill" class="bg-blue-500 text-white dark:bg-blue-600">
<z-icon zType="badge-check" />
Verified
</z-badge>
<z-badge zShape="pill" class="h-5 min-w-5 px-1 font-mono tabular-nums">8</z-badge>
<z-badge zShape="pill" zType="destructive" class="h-5 min-w-5 px-1 font-mono tabular-nums">99</z-badge>
<z-badge zShape="pill" zType="outline" class="h-5 min-w-5 px-1 font-mono tabular-nums">20+</z-badge>
</div>
</div>
`,
})
export class ZardDemoBadgeDefaultComponent {}
Use the CLI to add alert to your project.
npx zard-cli@latest add alertpnpm dlx zard-cli@latest add alertyarn dlx zard-cli@latest add alertbunx zard-cli@latest add alertNotification component for displaying important information to users with different severity levels.
Please verify your billing information and try again.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ZardIconComponent } from '../../icon/icon.component';
import { ZardAlertComponent } from '../alert.component';
@Component({
selector: 'z-demo-alert-basic',
imports: [ZardAlertComponent, ZardIconComponent],
standalone: true,
template: `
<div class="grid w-full max-w-xl items-start gap-4">
<z-alert
zIcon="circle-check"
zTitle="Success! Your changes have been saved"
zDescription="This is an alert with icon, title and description."
/>
<z-alert [zIcon]="customIcon" zTitle="This Alert has a title and an icon. No description." />
<ng-template #customIcon>
<z-icon zType="popcorn" />
</ng-template>
<z-alert zType="destructive" zTitle="Unable to process your payment." [zDescription]="customDescription" />
<ng-template #customDescription>
<p>Please verify your billing information and try again.</p>
<ul class="list-disc pl-5">
<li>Check your card details</li>
<li>Ensure sufficient funds</li>
<li>Verify billing address</li>
</ul>
</ng-template>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoAlertBasicComponent {}
Use the CLI to add table to your project.
npx zard-cli@latest add tablepnpm dlx zard-cli@latest add tableyarn dlx zard-cli@latest add tablebunx zard-cli@latest add tableData table component with sorting, filtering, pagination, and customizable column rendering.
| Name | Age | Address |
|---|---|---|
| John Brown | 32 | New York No. 1 Lake Park |
| Jim Green | 42 | London No. 1 Lake Park |
| Joe Black | 32 | Sidney No. 1 Lake Park |
import { Component } from '@angular/core';
import { ZardTableComponent } from '../table.component';
interface Person {
key: string;
name: string;
age: number;
address: string;
}
@Component({
selector: 'z-demo-table-simple',
imports: [ZardTableComponent],
standalone: true,
template: `
<table z-table>
<caption>A list of your recent invoices.</caption>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Address</th>
</tr>
</thead>
<tbody>
@for (data of listOfData; track data.key) {
<tr>
<td class="font-medium">{{ data.name }}</td>
<td>{{ data.age }}</td>
<td>{{ data.address }}</td>
</tr>
}
</tbody>
</table>
`,
})
export class ZardDemoTableSimpleComponent {
listOfData: Person[] = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
];
}