Jak używać
- Skopiuj polecenie instalacji i sprawdź źródła przed instalacją we własnym środowisku agenta.
- W oryginale sprawdź wymagane narzędzia, dane dostępowe i obsługiwane środowiska.
- Opisz dane wejściowe i oczekiwany rezultat; porównaj wynik ze źródłami.
npx skills add https://github.com/zard-ui/zardui --skill zardPrzed rozpoczęciem
- Instalacja nie obejmuje subskrypcji modelu, limitu API ani uprawnień do plików.
- Gwiazdki i instalacje pokazują aktywność, a nie niezależny test jakości lub bezpieczeństwa.
Treść z repozytorium z zachowaniem nagłówków, przykładów, kodu, tabel, linków i obrazów.
zard/ui
An Angular component library. Components are installed as source code into the user's project by the CLI — there is no runtime package to import from, and no component to npm install.
IMPORTANT: Run every CLI command with the project's own package runner:npx zard-cli,pnpm dlx zard-cli,yarn zard-cli, orbunx zard-cli— pick the one matchingpackageManagerincomponents.json. The examples below usenpx zard-cli; substitute the right runner.
Current Project Context
Read `components.json` at the project root before doing anything else. It is written by zard-cli init and is the whole configuration — there is no zard-cli info command to call.
{
"$schema": "https://zardui.com/schema.json",
"style": "css",
"icons": "lucide",
"rtl": false,
"projectType": "angular",
"appConfigFile": "src/app/app.config.ts",
"packageManager": "npm",
"tailwind": { "css": "src/styles.css", "baseColor": "neutral" },
"baseUrl": "src/app",
"aliases": {
"components": "@/shared/components",
"utils": "@/shared/utils",
"core": "@/shared/core",
"services": "@/shared/services",
"blocks": "@/shared/blocks"
}
}No components.json means the project has not been initialised — run init rather than writing component files by hand.
A components.json that exists but whose installed component source uses a renamed selector or an old file layout (core/css/tailwind.css instead of core/css/zard.css, a bare ::-webkit-scrollbar block in the global CSS, a button-group "divider" instead of "separator", a toast folder instead of sonner) belongs to a project predating the current registry. That is a job for the migration skill, which names every renamed selector precisely — not for guessing which shape is current.
For anything the file does not answer — what exists, what a component's API is, what it depends on — read the registry or use the MCP server. Never reconstruct a component API from memory.
Key Fields
- `aliases.components` → the import prefix for every component. Use the actual value; never hardcode
@/shared/components. The prefix can be anything (@app/...,~/...) — it is mapped intsconfig.json, ortsconfig.base.jsonin an Nx workspace. - `aliases.blocks` → the import prefix a block (
add dashboard-01,add login-01) is written under. Absent from acomponents.jsonwritten before blocks were installable — a re-run ofinitadds it. - `baseUrl` → the source root the aliases resolve against. Components are written under it.
- `projectType` →
angular,angular-library,nx,nx-library, oranalog. Decides which tsconfig holds the aliases, where Tailwind is configured, and whether anapp.config.tsexists at all. See cli.md. - `appConfigFile` → where
provideZard()is registered. Empty in a library — there the consuming app registers it. - `tailwind.css` → the global CSS file holding the theme tokens. Always edit this file; never create a second one.
- `tailwind.baseColor` → the theme preset:
neutral,stone,zinc,gray, orslate. - `icons` → the icon family the components are written with (
lucidetoday). Decides the@ng-icons/*package and the symbol names. See rules/icons.md. - `rtl` → declares layout direction intent. It does not change what gets installed.
- `packageManager` → use it for every dependency install (
pnpm add date-fns, notnpm install date-fns) and to pick the CLI runner. - `registryUrl` → optional. Present when the project installs from a registry other than
https://zardui.com/r. See registry.md.
Principles
- Install before importing. A component only exists once
zard-cli addhas written it. Check the components directory first; do not import what is not there. - Compose what exists. A settings page is Card + Field + Input + Button. A dashboard is Sidebar + Card + Chart + Table. Reach for custom markup only when nothing covers it.
- Variants before classes.
zType="outline",zSize="sm"— not aclassthat re-styles the component into the same thing. - Semantic tokens only.
bg-primary,text-muted-foreground. Neverbg-blue-500, never adark:colour override. - The library's own conventions apply to the code you write. Standalone,
OnPush,input(),z-prefixed inputs. See rules/angular.md.
Critical Rules
Always enforced. Each links to a file with Incorrect/Correct pairs.
Angular API → rules/angular.md
- Standalone with `imports`, `ChangeDetectionStrategy.OnPush`, `ViewEncapsulation.None`. No NgModules, no
Defaultchange detection. - Signal inputs: `input()`, `model()`, `output()`. No
@Input()/@Output()decorators in new code. - Selectors are `z-<name>` and/or `[z-<name>]`. Some components are element-only, some are attributes on a native tag (
input[z-input],button[z-button]). Use the one the component declares. - Composite components import their `Zard<Name>Imports` array, not the individual classes one by one.
- Never edit generated output.
apps/web/src/generated/**andpublic/r/*.jsonare build artefacts.
Styling → rules/styling.md
- Semantic tokens, never raw colours.
bg-primarynotbg-blue-600. - `class` is for layout, not for restyling. It is merged last and wins — which is exactly why it should not be used to override the component's own colours.
- `mergeClasses()`, not string concatenation. It is
twMerge(clsx(...)); plain interpolation loses the conflict resolution. - No `space-x-
/space-y-`. Use `flex` with `gap-`. - `size-
when width and height match.**size-4, notw-4 h-4`. - No `dark:` colour overrides. The tokens already switch.
- Tailwind v4 only. There is no
tailwind.config.js; the theme lives in CSS. - `scroll-fade` needs an overflow container; `shimmer` is text-only. Both are pure-CSS utilities from the
coreitem.
Composition → rules/composition.md
- Use the full composition.
z-cardwantsz-card-header/z-card-title/z-card-content/z-card-footer, not everything dumped into content. - Items belong to their group.
z-select-iteminsidez-select-group. - Dialogs, sheets, alert dialogs and drawers have two forms. Compose
z-dialog/z-sheet/z-alert-dialog/z-drawerin the template with[(zVisible)]and the header/title/description/footer children, or open the same panel from code throughZardDialogService/ZardSheetService/ZardAlertDialogService/ZardDrawerService. Never toggle them with a hand-writtenopenflag or@if. - Toasts go through `ZardSonnerService` —
show,success,error,promise. - Use the component instead of styled markup.
z-separatornot<hr>,z-skeletonnot ananimate-pulsediv,z-badgenot a styled span,z-emptynot a hand-built empty state.
Forms → rules/forms.md
- All three Angular form APIs are supported: Signal Forms, Reactive Forms, Template-driven. Follow whichever the project already uses.
- Form layout is `z-field-group` + `z-field`, never a
divwithspace-y-*. - Validation state is `data-invalid` on the field and `aria-invalid` on the control.
- Errors render in `z-field-error`, not a loose paragraph.
Typeset → rules/typeset.md
- Rendered markdown gets a `typeset` container, never a class per tag.
zard-cli add typesetinstalls the stylesheet. - Six variables govern it, three of which are the rhythm:
--typeset-size,--typeset-leading,--typeset-flow. - `not-typeset` on any component embedded in prose. It brings its own sizing.
- `typeset-scroll` around a wide table, instead of a hand-rolled overflow wrapper.
- Utilities beat it with no `!important` — every element selector sits inside
:where().
Icons → rules/icons.md
- Icons come from `@ng-icons/<family>` and are registered with `provideIcons` in `viewProviders`. An unregistered name renders nothing, silently.
- The family comes from `icons` in `components.json`. Do not assume
lucide. - No sizing classes on icons inside components. The component sizes them.
Key Patterns
// Host classes: computed + mergeClasses. Never assembled in the template.
protected readonly classes = computed(() => mergeClasses(cardVariants(), this.class()));
// Variants, not classes.
<button z-button zType="outline" zSize="sm">Save</button> // correct
<button z-button class="border bg-transparent px-2.5">Save</button> // wrong
// Spacing: gap-*, not space-y-*.
<div class="flex flex-col gap-4"> // correct
<div class="space-y-4"> // wrong
// Field: data-invalid on the field, aria-invalid on the control.
<div z-field [attr.data-invalid]="invalid || null">
<label z-field-label for="email">Email</label>
<input z-input id="email" [attr.aria-invalid]="invalid || null" />
<z-field-error>Enter a valid email.</z-field-error>
</div>
// Loading button: the zLoading input, not a hand-rolled spinner.
<button z-button [zLoading]="saving()" [zDisabled]="saving()">Save</button>Component Selection
| Need | Use |
|---|---|
| Action | z-button (zType: default, destructive, outline, secondary, ghost, link) |
| Grouped actions | z-button-group, z-toggle, z-toggle-group |
| Text input | input[z-input], textarea[z-textarea], z-input-group, z-input-otp |
| Choice | z-select, z-combobox, z-radio-group, z-checkbox, z-switch, z-slider |
| Dates | z-calendar, z-date-picker |
| Form structure | z-field-group, z-field, z-field-label, z-field-description, z-field-error |
| Data display | z-table, z-card, z-item, z-badge, z-avatar, z-chart |
| Navigation | z-navigation-menu, z-breadcrumb, z-tab-group, z-pagination |
| Nested / tree list | z-collapsible, nested — a folder tree is a z-collapsible inside a z-collapsible-content, not a dedicated tree component. See the composition rule. |
| Layout | z-sidebar (with z-sidebar-provider and z-sidebar-inset), z-separator, z-resizable, z-accordion, z-carousel |
| Overlays | z-dialog (modal), z-drawer (bottom/side sheet), z-sheet (side panel), z-alert-dialog (confirmation) — each also from code via its service —, z-popover, z-tooltip, z-dropdown |
| Command palette | z-command |
| Feedback | ZardSonnerService (toast), z-alert, z-progress, z-skeleton, z-spinner |
| Empty states | z-empty |
| Chat / messages | z-bubble, z-bubble-group, z-bubble-content, z-bubble-reactions |
| Keyboard hints | z-kbd |
| Rendered prose | typeset + a preset class (a stylesheet, not a component) — see rules/typeset.md |
Names are the registry names — the same string zard-cli add takes. Two names from an older registry, tree and layout, no longer exist: layout's header/content/sidebar shape was replaced by the sidebar component above; tree has no replacement component — nest z-collapsible instead, per the row above. A project installed before the removal may still have them; see the migration skill.
Non-component items
Not every registry name is a component you pick for a UI need — five install infrastructure instead:
| Item | What it is | Installed |
|---|---|---|
core | Shared directives, the overlay stack, provideZard(), and the theme CSS | Automatic — init installs it; no component declares it as a dependency |
utils | mergeClasses() (twMerge(clsx(...))) | Automatic — same as core |
utilities | The scroll-fade / shimmer CSS utilities — see rules/styling.md | zard-cli add utilities, or installed with a component that uses them |
dark-mode | The dark-mode service and the toggle script injected into index.html | Opt-in — zard-cli add dark-mode (interactive; needs an index.html path) |
typeset | The prose stylesheet for rendered markdown | Opt-in — zard-cli add typeset — see rules/typeset.md |
Workflow
- Read `components.json`. No file → run
init. Notealiases,baseUrl,icons,packageManager,projectType. - Check what is installed. List the components directory resolved from
aliases.components. Do not re-add what is there, and do not import what is not. - Find what exists. The registry index at
<registryUrl>/registry.jsonlists every item; the MCP server exposes the same thing aslist-componentsandsearch-components. - Read the real API before writing code.
get-component-docs(MCP) orhttps://zardui.com/docs/components/<name>.md. Every component page is published as Markdown. Guessing at inputs is the single most common failure mode. - Install.
npx zard-cli add <name>— dependencies of the component, both npm packages and other registry items, are resolved and installed with it. - Review what was written. Read the added files. Check the imports resolve under the project's real alias, and that the icon family matches
icons. - Never hand-fetch component source from GitHub. Use the CLI or the registry; the registry is what the project actually installs from.
Quick Reference
# Initialise a project (full-screen wizard).
npx zard-cli init
npx zard-cli init --type nx --project web # answer the wizard up front
npx zard-cli init --yes # accept the defaults; required without a TTY
# Add components.
npx zard-cli add button card dialog
npx zard-cli add # pick from the list
npx zard-cli add --all
npx zard-cli add button --overwrite # replace local changes — ask first
npx zard-cli add button --path src/app/ui # a directory other than the configured one
# Diagnose.
npx zard-cli add button --debug
npx zard-cli --versionThere is no search, view, diff, info, or build command — those are shadcn's. See cli.md for the full flag reference.
Detailed References
- cli.md —
initandadd, every flag, the five project types, headless behaviour - registry.md — the index, item and icon-catalog formats, JSON Schemas, pointing at your own registry
- mcp.md — the nine MCP tools, how to connect,
ZARD_REGISTRY_URL/ZARD_DOCS_URL - customization.md — theme tokens, CVA variants,
mergeClasses, extending a component - rules/angular.md — standalone,
input(), OnPush,ViewEncapsulation.None, selectors - rules/styling.md — Tailwind v4, semantic tokens,
mergeClasses, variants before raw classes, thescroll-fade/shimmerutilities - rules/composition.md — composing with what exists before inventing markup
- rules/forms.md — Signal Forms, Reactive Forms, Template-driven
- rules/icons.md — ng-icons,
provideIcons, the catalog, the configurable family - rules/typeset.md — styling rendered markdown with one container class instead of one per tag
- ../zard-migration/SKILL.md — a separate skill for a project whose installed component source predates the current registry (renamed selectors,
--overwrite, thecore/utils/utilitiessplit)


