Conversation
|
Note
|
| Cohort / File(s) | Summary |
|---|---|
Float Label Component Corelibs/zard/src/lib/components/float-label/float.label.component.ts, libs/zard/src/lib/components/float-label/float.label.variants.ts |
Introduces ZardFloatLabelComponent with signal-based class input, computed styling via CVA, browser-platform guards, and dynamic input-has-value toggling on focus/blur/input events; adds floatLabelStyles constant for comprehensive Tailwind-based state variants (focus, value, error/warning/success). |
Float Label Demoslibs/zard/src/lib/components/float-label/demo/default.ts, default.ts, input.ts, select.ts, status.ts, text-area.ts |
Adds four demo components (default, textarea, select, status) showcasing float-label integration with reactive forms and form state validation; introduces FLOAT_LABEL metadata constant for demo registration. |
Float Label Documentationlibs/zard/src/lib/components/float-label/doc/overview.md, api.md |
Adds markdown documentation describing float-label as a wrapper component providing floating label animation for form inputs. |
Float Label Testinglibs/zard/src/lib/components/float-label/float.label.spec.ts |
Comprehensive unit test suite validating component creation, focus/blur behavior, dynamic class application, status styling, custom class propagation, server-side guards, and event-driven state updates. |
Input Directive Enhancementlibs/zard/src/lib/components/input/input.directive.ts |
Extends ZardInputDirective with AfterViewInit/OnDestroy lifecycle hooks, injects Renderer2/NgControl/NgModel/FormControlName/FormControlDirective for form integration, adds subscription management for valueChanges tracking, implements updateInputState method to toggle input-has-value class and data-status attribute. |
Input Demo Refactoringlibs/zard/src/lib/components/input/demo/input.ts |
Reorders imports (swaps ZardDemoInputTextAreaComponent and ZardDemoInputStatusComponent positions). |
Select Component Enhancementlibs/zard/src/lib/components/select/select.component.ts |
Adds Overlay/Portal/platform-check imports, extends form integration with Renderer2 and Subscription for event handling, introduces updateSelectState method to toggle input-has-value class on trigger button based on value presence, subscribes to form value changes and focus/blur events, adds placeholder id for DOM targeting. |
Routing & Configurationapps/web/prerender-routes.txt, apps/web/src/app/shared/constants/routes.constant.ts |
Registers new float-label component route at /docs/components/float-label in prerender routes and component navigation constant. |
Sequence Diagram(s)
sequenceDiagram
participant User
participant FloatLabel as FloatLabel<br/>Component
participant Input as Input/Textarea<br/>Element
participant Renderer as Renderer2
User->>Input: Focus
Input->>FloatLabel: onInteraction() (focus event)
FloatLabel->>FloatLabel: updateLabelState()
FloatLabel->>Renderer: toggleClass(input-has-value)
Renderer->>Input: Apply class
User->>Input: Type value
Input->>FloatLabel: onInteraction() (input event)
FloatLabel->>FloatLabel: updateLabelState()
FloatLabel->>Renderer: Check element.value
alt Has value
Renderer->>Input: Add input-has-value
else Empty
Renderer->>Input: Remove input-has-value
end
User->>Input: Blur
Input->>FloatLabel: onInteraction() (blur event)
FloatLabel->>FloatLabel: updateLabelState()
note over FloatLabel: Maintains input-has-value if value exists
sequenceDiagram
participant FormControl as Form Control<br/>(Reactive/Template)
participant InputDirective as Input Directive
participant Renderer as Renderer2
FormControl->>InputDirective: ngAfterViewInit()
InputDirective->>FormControl: Subscribe to valueChanges
InputDirective->>InputDirective: Subscribe to input/change events
FormControl->>InputDirective: valueChanges emits
InputDirective->>InputDirective: updateInputState()
InputDirective->>Renderer: Toggle input-has-value class
InputDirective->>Renderer: Set data-status attribute
note over InputDirective: On component destroy
InputDirective->>InputDirective: ngOnDestroy()
InputDirective->>InputDirective: Unsubscribe from all subscriptions
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~50 minutes
- Input Directive public API expansion: Five new public injected dependencies (renderer, ngControl, ngModel, formControlName, formControlDirective) plus lifecycle hooks and subscription management—verify injection strategy follows Angular 17+ best practices with
inject()pattern and ensures no circular dependencies - Float Label DOM manipulation logic: Browser platform guards, ElementRef queries for nested inputs/textareas/buttons, and dynamic class toggling via Renderer2—ensure platform-agnostic execution and verify query selectors are resilient
- Form integration patterns: Subscription management across Input Directive, Select component, and potential Float Label interactions—verify proper cleanup in ngOnDestroy and no memory leaks
- Select component state tracking: New Overlay/Portal and Renderer2 usage alongside existing logic—ensure updateSelectState integrates smoothly with existing overlay/positioning without interference
- CVA styling integration: floatLabelStyles defines comprehensive Tailwind selectors for focus/value/status states—validate selector specificity and Tailwind v4 compatibility
Possibly related PRs
- Feat/doc ssr support #269: Modifies the same demo file (
libs/zard/src/lib/components/input/demo/input.ts) to add description metadata to the INPUT constant, which could conflict with or complement the import reordering in this PR.
Suggested reviewers
- Luizgomess
- ribeiromatheuss
- srizzon
Poem
✨ A label floats with graceful ease,
While inputs dance and states find peace,
Forms track changes, Directives guide,
Selects respond with every stride,
Angular signals now reside! 🎯
Pre-merge checks and finishing touches
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The title 'feat: Float Input Label' accurately summarizes the main change—implementing a new floating label component. It is concise, clear, and directly reflects the primary objective of the pull request. |
| Description check | ✅ Passed | The description covers the main implementation details, specifies the type of change (new feature), includes testing checklist validation across browsers, but lacks Figma/implementation screenshots and a related issue link. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 4
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (4)
apps/web/public/components/input/demo/float.input.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/installation/manual/empty.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/installation/manual/input.mdis excluded by!apps/web/public/**and included byapps/**package-lock.jsonis excluded by!**/package-lock.jsonand included by none
📒 Files selected for processing (4)
libs/zard/src/lib/components/input/demo/float.input.ts(1 hunks)libs/zard/src/lib/components/input/demo/input.ts(2 hunks)libs/zard/src/lib/components/input/float.label.component.ts(1 hunks)libs/zard/src/lib/components/input/input.directive.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
libs/zard/src/lib/components/**/*.component.ts
📄 CodeRabbit inference engine (CLAUDE.md)
libs/zard/src/lib/components/**/*.component.ts: Angular components must be standalone (standalone: true)
Use ChangeDetectionStrategy.OnPush for all Angular components
Bind host class to computed classes via host: { '[class]': 'classes()' }
Use signal-based inputs via input() for component inputs (e.g., variant, size, class)
Provide a selector in the form 'z-[name], [z-[name]]' for each component
Files:
libs/zard/src/lib/components/input/float.label.component.ts
libs/zard/src/lib/components/**/*.{component,variants}.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use tailwind-merge for class merging and clsx for conditional classes when composing CSS classes
Files:
libs/zard/src/lib/components/input/float.label.component.ts
libs/zard/src/lib/components/*/*.component.ts
📄 CodeRabbit inference engine (CONTRIBUTING.md)
libs/zard/src/lib/components/*/*.component.ts: Place each Angular component in its own folder and name the main file [name].component.ts under libs/zard/src/lib/components/[name]/
Components must be standalone (standalone: true) and use ChangeDetectionStrategy.OnPush
Component selector should follow: 'z-[name], [z-[name]]' (element and attribute selectors)
Use signal-based inputs via input() for public inputs (e.g., variant, size, class)
Host-bind the class attribute and compute classes via computed() + mergeClasses(CVA(...), class)
Use Tailwind utility classes and resolve class conflicts via tailwind-merge (through mergeClasses) in components
Files:
libs/zard/src/lib/components/input/float.label.component.ts
libs/zard/src/lib/components/**/demo/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Place demo files under a demo/ directory (including a main demo export file, default.ts, and variant example files)
Files:
libs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.ts
🧠 Learnings (21)
📓 Common learnings
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-10-17T17:12:22.571Z
Learning: Applies to libs/blocks/src/lib/*/*.component.{ts,html} : Use ZardUI form components for validation (FormField, FormLabel, FormControl) in blocks with forms
Learnt from: mikij
Repo: zard-ui/zardui PR: 318
File: libs/zard/src/lib/components/select/demo/default.ts:21-21
Timestamp: 2025-11-10T21:46:33.213Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, intentionally showing different patterns (e.g., primitive values vs signals) across different demos is valuable for demonstrating the flexibility of Angular features like two-way binding.
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use signal-based inputs via input() for component inputs (e.g., variant, size, class)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Use signal-based inputs via input() for public inputs (e.g., variant, size, class)
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from libs/zard/src/lib/components/components.ts
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-17T17:12:22.571Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-10-17T17:12:22.571Z
Learning: Applies to libs/blocks/src/lib/*/*.component.{ts,html} : Use ZardUI form components for validation (FormField, FormLabel, FormControl) in blocks with forms
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Component selector should follow: 'z-[name], [z-[name]]' (element and attribute selectors)
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Place each Angular component in its own folder and name the main file [name].component.ts under libs/zard/src/lib/components/[name]/
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/demo/float.input.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use signal-based inputs via input() for component inputs (e.g., variant, size, class)
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Provide a selector in the form 'z-[name], [z-[name]]' for each component
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Use signal-based inputs via input() for public inputs (e.g., variant, size, class)
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Use Tailwind utility classes and resolve class conflicts via tailwind-merge (through mergeClasses) in components
Applied to files:
libs/zard/src/lib/components/input/float.label.component.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from the barrel file libs/zard/src/lib/components/components.ts
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Bind host class to computed classes via host: { '[class]': 'classes()' }
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Host-bind the class attribute and compute classes via computed() + mergeClasses(CVA(...), class)
Applied to files:
libs/zard/src/lib/components/input/float.label.component.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-31T10:03:18.563Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 299
File: libs/zard/src/lib/components/select/select.component.ts:34-38
Timestamp: 2025-10-31T10:03:18.563Z
Learning: In Angular 19+ (including Angular 20 used in this project), components are standalone by default. The `standalone: true` flag is redundant and should be omitted unless explicitly setting `standalone: false` to opt out.
Applied to files:
libs/zard/src/lib/components/input/float.label.component.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/demo/**/*.ts : Place demo files under a demo/ directory (including a main demo export file, default.ts, and variant example files)
Applied to files:
libs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.ts
📚 Learning: 2025-11-10T21:46:33.213Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 318
File: libs/zard/src/lib/components/select/demo/default.ts:21-21
Timestamp: 2025-11-10T21:46:33.213Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, intentionally showing different patterns (e.g., primitive values vs signals) across different demos is valuable for demonstrating the flexibility of Angular features like two-way binding.
Applied to files:
libs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.ts
📚 Learning: 2025-11-04T20:46:01.373Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 309
File: libs/zard/src/lib/components/select/demo/multi-select.ts:23-27
Timestamp: 2025-11-04T20:46:01.373Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, console.log statements are acceptable and often intentional to demonstrate reactivity and help users understand how the component works.
Applied to files:
libs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/demo/default.ts : Each component must provide a demo/default.ts exporting a DefaultExample with name, code, and lazy-loaded component
Applied to files:
libs/zard/src/lib/components/input/demo/float.input.tslibs/zard/src/lib/components/input/demo/input.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/index.ts : Maintain the library public entry point in libs/zard/src/index.ts
Applied to files:
libs/zard/src/lib/components/input/demo/input.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use ChangeDetectionStrategy.OnPush for all Angular components
Applied to files:
libs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.{component,variants}.ts : Use tailwind-merge for class merging and clsx for conditional classes when composing CSS classes
Applied to files:
libs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.variants.ts : Define styling variants with Class Variance Authority (CVA) in a companion <name>.variants.ts file
Applied to files:
libs/zard/src/lib/components/input/input.directive.ts
🧬 Code graph analysis (2)
libs/zard/src/lib/components/input/float.label.component.ts (1)
libs/zard/src/lib/components/input/demo/float.input.ts (1)
Component(6-17)
libs/zard/src/lib/components/input/demo/float.input.ts (1)
libs/zard/src/lib/components/input/float.label.component.ts (1)
Component(4-94)
🔇 Additional comments (2)
libs/zard/src/lib/components/input/demo/input.ts (1)
3-6: Float-label demo wiring looks correct and consistentThe new
ZardFloatLabelDemoComponentimport and the'float-label'entry inINPUT.examplesare correctly hooked up and consistent with the existing demo structure (column layout etc.). No issues here.Also applies to: 18-22
libs/zard/src/lib/components/input/input.directive.ts (1)
39-74: Guard DOM event subscriptions for SSR and add OnPush detection strategyLines 39–74 need two critical fixes:
Wrap
fromEvent()subscriptions with SSR guard (lines 55–56):fromEvent(nativeElement, 'input'/'change')will throw on server wherenativeElementlacksaddEventListener. InjectPLATFORM_ID, computeconst isBrowser = isPlatformBrowser(this.platformId), and guard bothfromEventcalls plus the initialupdateInputState()inside anif (isBrowser)block. Mirror the pattern used insheet-ref.ts,dialog-ref.ts, andmenu.directive.tsin the same codebase.Mark
updateInputStateasprivate readonly(line 61): Arrow function should not be part of the public API surface.Add brief comment on
setTimeout(line 39): Document that this ensures form directives/controls are fully wired before subscriptions attach (control initialization timing).Add
ChangeDetectionStrategy.OnPushto the@Directivedecorator per coding guidelines.⛔ Skipped due to learnings
Learnt from: CR Repo: zard-ui/zardui PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-10-15T00:51:30.882Z Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use ChangeDetectionStrategy.OnPush for all Angular components
| import { Component } from '@angular/core'; | ||
|
|
||
| import { ZardFloatLabelComponent } from '../float.label.component'; | ||
| import { ZardInputDirective } from '../input.directive'; | ||
|
|
||
| @Component({ | ||
| selector: 'z-demo-input-float-input', | ||
| standalone: true, | ||
| imports: [ZardInputDirective, ZardFloatLabelComponent], | ||
| template: ` | ||
| <zard-float-label> | ||
| <input z-input /> | ||
| <label>Float Label</label> | ||
| </zard-float-label> | ||
| `, | ||
| }) | ||
| export class ZardFloatLabelDemoComponent {} |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Optional: add OnPush change detection to align demo with library components
The demo is simple and works as-is. To stay in line with the rest of the library’s Angular best practices, you could also set changeDetection: ChangeDetectionStrategy.OnPush here (and import ChangeDetectionStrategy), even though it won’t change behaviour today.
Example:
-import { Component } from '@angular/core';
+import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'z-demo-input-float-input',
standalone: true,
imports: [ZardInputDirective, ZardFloatLabelComponent],
+ changeDetection: ChangeDetectionStrategy.OnPush,
template: `Purely a consistency/refinement tweak; not a blocker.
As per coding guidelines
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { Component } from '@angular/core'; | |
| import { ZardFloatLabelComponent } from '../float.label.component'; | |
| import { ZardInputDirective } from '../input.directive'; | |
| @Component({ | |
| selector: 'z-demo-input-float-input', | |
| standalone: true, | |
| imports: [ZardInputDirective, ZardFloatLabelComponent], | |
| template: ` | |
| <zard-float-label> | |
| <input z-input /> | |
| <label>Float Label</label> | |
| </zard-float-label> | |
| `, | |
| }) | |
| export class ZardFloatLabelDemoComponent {} | |
| import { Component, ChangeDetectionStrategy } from '@angular/core'; | |
| import { ZardFloatLabelComponent } from '../float.label.component'; | |
| import { ZardInputDirective } from '../input.directive'; | |
| @Component({ | |
| selector: 'z-demo-input-float-input', | |
| standalone: true, | |
| imports: [ZardInputDirective, ZardFloatLabelComponent], | |
| changeDetection: ChangeDetectionStrategy.OnPush, | |
| template: ` | |
| <zard-float-label> | |
| <input z-input /> | |
| <label>Float Label</label> | |
| </zard-float-label> | |
| `, | |
| }) | |
| export class ZardFloatLabelDemoComponent {} |
🤖 Prompt for AI Agents
In libs/zard/src/lib/components/input/demo/float.input.ts lines 1-17, the demo
component lacks explicit changeDetection; add ChangeDetectionStrategy.OnPush to
the @Component decorator and import ChangeDetectionStrategy from '@angular/core'
so the demo aligns with the library's OnPush convention: update the import list
to include ChangeDetectionStrategy and add changeDetection:
ChangeDetectionStrategy.OnPush to the component metadata.
There was a problem hiding this comment.
@mikij, perfect! Here's the updated code with OnPush change detection:
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { ZardFloatLabelComponent } from '../float.label.component';
import { ZardInputDirective } from '../input.directive';
@Component({
selector: 'z-demo-input-float-input',
standalone: true,
imports: [ZardInputDirective, ZardFloatLabelComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<zard-float-label>
<input z-input />
<label>Float Label</label>
</zard-float-label>
`,
})
export class ZardFloatLabelDemoComponent {}This aligns the demo with the library's Angular best practices! 🚀
🧠 Learnings used
Learnt from: mikij
Repo: zard-ui/zardui PR: 318
File: libs/zard/src/lib/components/select/demo/default.ts:21-21
Timestamp: 2025-11-10T21:46:33.213Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, intentionally showing different patterns (e.g., primitive values vs signals) across different demos is valuable for demonstrating the flexibility of Angular features like two-way binding.
Learnt from: mikij
Repo: zard-ui/zardui PR: 309
File: libs/zard/src/lib/components/select/demo/multi-select.ts:23-27
Timestamp: 2025-11-04T20:46:01.373Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, console.log statements are acceptable and often intentional to demonstrate reactivity and help users understand how the component works.
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/demo/**/*.ts : Place demo files under a demo/ directory (including a main demo export file, default.ts, and variant example files)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use signal-based inputs via input() for component inputs (e.g., variant, size, class)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/demo/default.ts : Each component must provide a demo/default.ts exporting a DefaultExample with name, code, and lazy-loaded component
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-10-17T17:12:22.571Z
Learning: Applies to libs/blocks/src/lib/*/*.component.{ts,html} : Use ZardUI form components for validation (FormField, FormLabel, FormControl) in blocks with forms
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from libs/zard/src/lib/components/components.ts
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Use signal-based inputs via input() for public inputs (e.g., variant, size, class)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Provide a selector in the form 'z-[name], [z-[name]]' for each component
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Component selector should follow: 'z-[name], [z-[name]]' (element and attribute selectors)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use ChangeDetectionStrategy.OnPush for all Angular components
Learnt from: mikij
Repo: zard-ui/zardui PR: 299
File: libs/zard/src/lib/components/select/select.component.ts:34-38
Timestamp: 2025-10-31T10:03:18.563Z
Learning: In Angular 19+ (including Angular 20 used in this project), components are standalone by default. The `standalone: true` flag is redundant and should be omitted unless explicitly setting `standalone: false` to opt out.
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Use the provided Angular best practices in docs/angular-llm.txt when making changes
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Place each Angular component in its own folder and name the main file [name].component.ts under libs/zard/src/lib/components/[name]/
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from the barrel file libs/zard/src/lib/components/components.ts
If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!
| import { Component, ElementRef, AfterViewInit, ViewEncapsulation, Renderer2, HostListener, Inject, PLATFORM_ID } from '@angular/core'; | ||
|
|
||
| @Component({ | ||
| selector: 'zard-float-label', | ||
| standalone: true, | ||
| template: `<ng-content />`, | ||
| encapsulation: ViewEncapsulation.None, | ||
| styles: ` |
There was a problem hiding this comment.
🧩 Analysis chain
Align component metadata with ZardUI conventions (selector, OnPush, standalone)
- The selector
'zard-float-label'doesn’t follow the documented'z-[name], [z-[name]]'pattern and only exposes an element selector. To stay consistent and avoid later churn, I’d strongly suggest switching to something likeselector: 'z-float-label, [z-float-label]'and updating usages infloat.input.tsaccordingly. - Add
changeDetection: ChangeDetectionStrategy.OnPushto match the rest of the component library and the stated best practice. - In Angular 19+/20 the
standalone: trueflag is redundant; you can safely drop it unless you explicitly opt out withstandalone: false.
A possible tweak (you’ll also need to adjust the demo template to the new selector):
-import { Component, ElementRef, AfterViewInit, ViewEncapsulation, Renderer2, HostListener, Inject, PLATFORM_ID } from '@angular/core';
+import { Component, ElementRef, AfterViewInit, ViewEncapsulation, Renderer2, HostListener, Inject, PLATFORM_ID, ChangeDetectionStrategy } from '@angular/core';
@Component({
- selector: 'zard-float-label',
- standalone: true,
+ selector: 'z-float-label, [z-float-label]',
+ changeDetection: ChangeDetectionStrategy.OnPush,
template: `<ng-content />`,
encapsulation: ViewEncapsulation.None,You may also want to revisit the dedicated CSS block later and see whether pieces of it can be expressed via the existing Tailwind/CVA stack to reduce bespoke styling.
As per coding guidelines
I'll verify the concerns in the review comment by inspecting the actual codebase.
🏁 Script executed:
#!/bin/bash
# Check the current state of float.label.component.ts
echo "=== float.label.component.ts ==="
cat libs/zard/src/lib/components/input/float.label.component.ts
echo -e "\n=== float.input.ts (to see how float-label is used) ==="
cat libs/zard/src/lib/components/input/float.input.ts | head -50
echo -e "\n=== Check Angular version ==="
cat package.json | grep -A2 '"@angular/core"'
echo -e "\n=== Sample selector patterns from other components ==="
rg -A1 "selector:\s*'" libs/zard/src/lib/components --type ts | head -20Length of output: 4312
🏁 Script executed:
#!/bin/bash
# Find package.json in monorepo
echo "=== Finding package.json ==="
find . -maxdepth 2 -name "package.json" -type f
echo -e "\n=== Main component selectors (exclude demos) ==="
rg "selector:\s*'" libs/zard/src/lib/components --type ts -A1 | grep -v "/demo/" | head -30
echo -e "\n=== Check ChangeDetectionStrategy usage ==="
rg "ChangeDetectionStrategy.OnPush" libs/zard/src/lib/components --type ts | head -10
echo -e "\n=== Files containing 'float' in input folder ==="
fd . libs/zard/src/lib/components/input --type fLength of output: 2789
🏁 Script executed:
#!/bin/bash
# Check for Angular version
echo "=== Angular version from dependencies ==="
find . -name "*.json" -type f | xargs grep -l '"@angular/core"' 2>/dev/null | head -3
echo -e "\n=== Searching all component selectors for dual [z-*] patterns ==="
rg "selector:\s*['\"]z-.*,\s*\[z-" libs/zard/src/lib/components --type ts
echo -e "\n=== Check if any non-demo component uses dual selector ==="
rg "selector:" libs/zard/src/lib/components --type ts -A1 | grep -E "\[z-" | head -5
echo -e "\n=== Verify ChangeDetectionStrategy import in float.label.component.ts ==="
head -1 libs/zard/src/lib/components/input/float.label.component.ts
echo -e "\n=== Check actual import for ChangeDetectionStrategy across components ==="
rg "ChangeDetectionStrategy" libs/zard/src/lib/components/toggle/toggle.component.ts -B5 | head -10Length of output: 3404
Fix selector, add ChangeDetectionStrategy.OnPush, and remove @HostListener
The component violates established ZardUI patterns and should be aligned:
- Selector: Currently
'zard-float-label'breaks convention. Must follow'z-float-label, [z-float-label]'(dual element/attribute pattern used consistently across switch, radio, checkbox, avatar, alert, form, and many other components). - Missing ChangeDetectionStrategy.OnPush: All comparable components (toggle, switch, tabs, toast, skeleton, slider, etc.) use OnPush. Add this import and include
changeDetection: ChangeDetectionStrategy.OnPushin metadata. - @HostListener ineffective here: The decorators on
'input','focus','blur'won't reliably fire on the wrapper element when child inputs receive focus/blur. SinceupdateLabelState()is called inngAfterViewInit()and tracks value changes, this pattern is redundant. Simplify to only the input event if cross-browser value-tracking is critical, or rely on CSS:has()which already handles focus/blur states.
-import { Component, ElementRef, AfterViewInit, ViewEncapsulation, Renderer2, HostListener, Inject, PLATFORM_ID } from '@angular/core';
+import { Component, ElementRef, AfterViewInit, ViewEncapsulation, Renderer2, HostListener, Inject, PLATFORM_ID, ChangeDetectionStrategy } from '@angular/core';
@Component({
- selector: 'zard-float-label',
+ selector: 'z-float-label, [z-float-label]',
+ changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { Component, ElementRef, AfterViewInit, ViewEncapsulation, Renderer2, HostListener, Inject, PLATFORM_ID } from '@angular/core'; | |
| @Component({ | |
| selector: 'zard-float-label', | |
| standalone: true, | |
| template: `<ng-content />`, | |
| encapsulation: ViewEncapsulation.None, | |
| styles: ` | |
| import { Component, ElementRef, AfterViewInit, ViewEncapsulation, Renderer2, HostListener, Inject, PLATFORM_ID, ChangeDetectionStrategy } from '@angular/core'; | |
| @Component({ | |
| selector: 'z-float-label, [z-float-label]', | |
| changeDetection: ChangeDetectionStrategy.OnPush, | |
| standalone: true, | |
| template: `<ng-content />`, | |
| encapsulation: ViewEncapsulation.None, | |
| styles: ` |
🤖 Prompt for AI Agents
In libs/zard/src/lib/components/input/float.label.component.ts around lines 2 to
9, update the component metadata and decorators to follow ZardUI conventions:
change the selector from 'zard-float-label' to the dual-element/attribute
pattern 'z-float-label, [z-float-label]'; import ChangeDetectionStrategy from
@angular/core and add changeDetection: ChangeDetectionStrategy.OnPush to the
@Component metadata; remove the @HostListener decorators (and any associated
focus/blur handler methods) since they are ineffective on the wrapper element
and redundant with ngAfterViewInit/value tracking or CSS :has() behavior; if
input event handling is still required keep a single input listener bound
directly to the inner input element rather than HostListener on the wrapper.
There was a problem hiding this comment.
do not follow this comment about selector if this is not acting as directive
There was a problem hiding this comment.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
| @HostListener('input', ['$event']) | ||
| @HostListener('focus', ['$event']) | ||
| @HostListener('blur', ['$event']) | ||
| onInteraction(event: Event) { | ||
| this.updateLabelState(); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
Tighten HostListener usage; focus/blur listeners are effectively dead code
@HostListener('focus')/@HostListener('blur')on the wrapper element won’t fire when the projected<input>/<textarea>/<button>gains or loses focus, becausefocus/blurdon’t bubble from the child control. Right now, only theinputlistener is doing any work.- We’re also not using the
$eventparameter.
To simplify and avoid misleading HostListeners while still updating the value state, you can reduce this to just the input event and drop $event entirely:
- @HostListener('input', ['$event'])
- @HostListener('focus', ['$event'])
- @HostListener('blur', ['$event'])
- onInteraction(event: Event) {
- this.updateLabelState();
- }
+ @HostListener('input')
+ onInput() {
+ this.updateLabelState();
+ }This also keeps HostListener usage minimal, as recommended, while leaving focus handling entirely to the :has(...:focus) CSS.
As per coding guidelines
I'll verify the component structure and validate the review comment claims.
🏁 Script executed:
#!/bin/bash
# View the float.label.component.ts file to inspect the HostListener usage and component structure
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs catLength of output: 233
🏁 Script executed:
#!/bin/bash
# Search for any other @HostListener or @HostBinding usage in the same file
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "HostListener\|HostBinding"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check if updateLabelState is called elsewhere in the file
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "updateLabelState"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Verify component configuration (standalone, changeDetection, inputs, etc.)
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n -A 5 "^@Component"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check the overall structure: class definition, imports, and ChangeDetectionStrategy usage
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs head -30Length of output: 233
🏁 Script executed:
#!/bin/bash
# Look for signal-based inputs (input() function) usage
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "= input"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check if there's a computed classes or host binding for classes
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "classes\|host.*class"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Inspect lines 65-85 for broader context around the HostListener methods
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs sed -n '65,85p'Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check if any other input/focus/blur listeners exist elsewhere in the codebase
rg -n "HostListener.*blur|HostListener.*focus" libs/zard/src/lib/components/input/Length of output: 198
🏁 Script executed:
#!/bin/bash
# Verify if there are any other event handlers or listeners for focus/blur
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n -i "focus\|blur" | grep -v "^Binary"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Look at the updateLabelState method to understand what it does
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n -A 10 "updateLabelState()"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check for ChangeDetectionStrategy usage
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "ChangeDetectionStrategy"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Look for any CSS that might use :has(:focus) selector
fd -e "float.label.*.css\|float.label.*.scss\|float.label.*.style" --path "*input*" | xargs cat 2>/dev/null || echo "No separate style file found"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check for inline styles in the component
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n -A 50 "styles:\|styleUrls:" | head -60Length of output: 233
🏁 Script executed:
#!/bin/bash
# Verify if the component is using proper Angular signal-based patterns
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "input\(\)\|computed\(\)\|signal\(\)"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check host configuration and class binding strategy
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "host:" -A 3Length of output: 233
🏁 Script executed:
#!/bin/bash
# Full file inspection for context
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs wc -lLength of output: 235
🏁 Script executed:
#!/bin/bash
# Get complete file content with line numbers
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs cat -nLength of output: 233
🏁 Script executed:
#!/bin/bash
# Look for any CSS :has selector patterns that might rely on focus state
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n ":has"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check if the onInteraction method's $event is ever used
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "event\." | grep -A 5 -B 5 "onInteraction"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Verify component selector format
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "selector:"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check if standalone is set to true
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "standalone"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Look for any @HostBinding usage on the class attribute or other bindings
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "@HostBinding"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Verify whether the component has a form-related context that might rely on focus handling
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "FormControl\|ngModel\|formControl"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check template to see if there are event bindings for focus/blur
fd -e "float.label.component.html" --path "*input*" | head -1 | xargs cat 2>/dev/null || echo "No template file; check inline template in component"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check for inline template
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "template:" -A 50Length of output: 233
🏁 Script executed:
#!/bin/bash
# Search for any comments explaining the focus/blur listener logic
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n -B 3 "HostListener.*focus\|HostListener.*blur\|HostListener.*input"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check if event.target is used anywhere in the component
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "event\.target\|event\." Length of output: 233
🏁 Script executed:
#!/bin/bash
# Look at surrounding context for the onInteraction method signature
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n -B 5 "onInteraction"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Verify the complete structure of the component and list all methods
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*("Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check if there's a specific implementation reason for listening to focus/blur (e.g., to sync child state)
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n -C 15 "@HostListener"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Final verification: grep all event listener related to input, focus, blur in the component
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs egrep -n "input|focus|blur" | head -30Length of output: 233
🏁 Script executed:
#!/bin/bash
# Look for any child component or projected content handling
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "ng-content\|@ContentChild\|@ViewChild"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Check if the component uses ::ng-deep or any CSS targeting that might justify focus/blur listeners
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs grep -n "ng-deep\|::ng-deep"Length of output: 233
🏁 Script executed:
#!/bin/bash
# Verify by examining implementation directly - get the method body
fd -e "float.label.component.ts" --path "*input*" | head -1 | xargs sed -n '71,76p'Length of output: 233
🏁 Script executed:
#!/bin/bash
# Complete view of the entire file to understand context
fd -e "float.label.component.ts" --path "*input*" | head -1Length of output: 233
🏁 Script executed:
#!/bin/bash
# Get the path and show the full file
find . -name "float.label.component.ts" -type f 2>/dev/null | head -1Length of output: 61
🏁 Script executed:
#!/bin/bash
# Direct file path lookup and display
find . -path "*input*float.label.component.ts" -type f 2>/dev/null | xargs catLength of output: 2872
🏁 Script executed:
#!/bin/bash
# Try alternative search pattern
find libs -name "*float*label*.ts" -type f 2>/dev/null | head -5Length of output: 59
🏁 Script executed:
#!/bin/bash
# List all TypeScript files in the input component directory
find libs/zard/src/lib/components/input -name "*.ts" -type f 2>/dev/nullLength of output: 585
🏁 Script executed:
#!/bin/bash
# View all files in the input directory
ls -la libs/zard/src/lib/components/input/ 2>/dev/null || echo "Directory not found"Length of output: 508
🏁 Script executed:
#!/bin/bash
# Check if the directory structure matches the expected path
find libs/zard/src/lib/components -type d -name "input" 2>/dev/nullLength of output: 34
🏁 Script executed:
#!/bin/bash
# Search for float.label pattern anywhere in the libs directory
find libs -name "*float*" -type f 2>/dev/null | head -10Length of output: 114
🏁 Script executed:
#!/bin/bash
# Broad search for label component files
find libs -name "*label*.component.ts" -type f 2>/dev/null | head -10Length of output: 125
🏁 Script executed:
#!/bin/bash
# Look in zard components for any file containing "float"
find libs/zard -name "*.ts" -type f 2>/dev/null | xargs grep -l "float" | head -5Length of output: 163
🏁 Script executed:
#!/bin/bash
# Try rg to search for the HostListener pattern with focus/blur
rg -l "HostListener.*focus.*blur|HostListener.*blur.*focus" libs/zard/ 2>/dev/null | head -5Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search for HostListener specifically with blur
rg "HostListener.*blur" libs/zard/src/lib/components/ 2>/dev/null | head -5Length of output: 95
🏁 Script executed:
#!/bin/bash
# Search for @HostListener in input components
rg "@HostListener" libs/zard/src/lib/components/input 2>/dev/null | head -20Length of output: 289
🏁 Script executed:
#!/bin/bash
# List all components in the input directory
find libs/zard/src/lib/components/input -type f 2>/dev/nullLength of output: 682
🏁 Script executed:
#!/bin/bash
# Check if libs/zard directory exists
ls -la libs/zard/src/lib/components/ 2>/dev/null | head -20Length of output: 1084
🏁 Script executed:
#!/bin/bash
# Find all component files
find . -name "*.component.ts" -path "*input*" 2>/dev/null | head -10Length of output: 195
🏁 Script executed:
#!/bin/bash
# Search for files that contain both HostListener and updateLabelState
rg -l "HostListener.*updateLabelState|updateLabelState.*HostListener" . 2>/dev/null | head -5Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search for updateLabelState method
rg -n "updateLabelState" . 2>/dev/null | head -10Length of output: 525
🏁 Script executed:
#!/bin/bash
# Look for files with input, focus, blur HostListeners together
rg "HostListener.*input.*HostListener.*focus.*HostListener.*blur" . 2>/dev/null | head -5Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search with multiline pattern for the exact code snippet
rg -U "@HostListener\('input'.*@HostListener\('focus'.*@HostListener\('blur'" . 2>/dev/null | head -5Length of output: 0
🏁 Script executed:
#!/bin/bash
# Try to find by exact method name onInteraction
rg -n "onInteraction" . 2>/dev/null | head -10Length of output: 179
🏁 Script executed:
#!/bin/bash
# Check repository structure
find . -type d -name "zard" | head -5Length of output: 11
🏁 Script executed:
#!/bin/bash
# List current directory to understand structure
ls -la | head -20Length of output: 389
🏁 Script executed:
#!/bin/bash
# Get git info about the PR
git log --oneline -5 2>/dev/null || echo "Not a git repo or git not available"Length of output: 266
🏁 Script executed:
#!/bin/bash
# Show changed files in PR
git diff --name-only HEAD~1..HEAD 2>/dev/null | grep -i "label\|input" | head -10Length of output: 315
🏁 Script executed:
#!/bin/bash
# Find modified files with HostListener
git diff --name-only HEAD~1..HEAD 2>/dev/null | xargs -I {} grep -l "HostListener" {} 2>/dev/null | head -5Length of output: 104
🏁 Script executed:
#!/bin/bash
# Search all TypeScript files for the code pattern from the review
rg -A 5 "@HostListener\('input'" . --type ts 2>/dev/null | head -30Length of output: 546
🏁 Script executed:
#!/bin/bash
# Search for the exact error pattern
rg -n "onInteraction" --type ts 2>/dev/null | head -10Length of output: 94
🏁 Script executed:
#!/bin/bash
# Alternative: search by exact line content
rg "updateLabelState" --type ts 2>/dev/null | head -20Length of output: 268
🏁 Script executed:
#!/bin/bash
# Check if file exists at exact path
test -f "libs/zard/src/lib/components/input/float.label.component.ts" && echo "File exists" || echo "File not found"Length of output: 11
🏁 Script executed:
#!/bin/bash
# If it exists, display it
if [ -f "libs/zard/src/lib/components/input/float.label.component.ts" ]; then
cat "libs/zard/src/lib/components/input/float.label.component.ts"
else
echo "File does not exist at expected path"
# Try to find it
find . -name "float.label.component.ts" 2>/dev/null
fiLength of output: 2872
🏁 Script executed:
#!/bin/bash
# List component directory if it exists
if [ -d "libs/zard/src/lib/components/input" ]; then
ls -la "libs/zard/src/lib/components/input/"
else
find . -type d -name "input" | grep components | head -5
fiLength of output: 508
🏁 Script executed:
#!/bin/bash
# Comprehensive search using multiple strategies
echo "=== Searching for float.label component ===" && \
(find . -name "float.label.component.ts" 2>/dev/null || echo "Not found via find") && \
echo "=== Searching via rg ===" && \
(rg -l "float.label" . 2>/dev/null || echo "Not found via rg") && \
echo "=== Searching for onInteraction method ===" && \
(rg -l "onInteraction" . 2>/dev/null | head -3 || echo "Not found")Length of output: 554
🏁 Script executed:
#!/bin/bash
# Show repository structure
tree -L 3 libs/zard/src/lib/components 2>/dev/null || find libs/zard/src/lib/components -maxdepth 3 -type f 2>/dev/null | head -20Length of output: 12757
🏁 Script executed:
#!/bin/bash
# PWD and repo info
pwd && echo "---" && find . -maxdepth 2 -name ".git" -o -name "package.json" | head -5Length of output: 29
Remove dead focus/blur listeners and unused $event parameter; input tracking via CSS :has(:focus) is already in place
The review is accurate. @HostListener('focus') and @HostListener('blur') on the host component never fire because these events don't bubble from the projected child inputs. The CSS already uses :has(input:focus), :has(textarea:focus), etc., making the focus listeners redundant. Additionally, the event: Event parameter is never used in onInteraction().
Apply the suggested refactor to keep only the functional input listener:
- @HostListener('input', ['$event'])
- @HostListener('focus', ['$event'])
- @HostListener('blur', ['$event'])
- onInteraction(event: Event) {
- this.updateLabelState();
- }
+ @HostListener('input')
+ onInput() {
+ this.updateLabelState();
+ }🤖 Prompt for AI Agents
In libs/zard/src/lib/components/input/float.label.component.ts around lines 71
to 76, remove the dead @HostListener('focus') and @HostListener('blur')
decorators and the unused event parameter from onInteraction; keep only
@HostListener('input') so the method becomes parameterless (onInteraction()) and
rely on the existing CSS :has(...) focus handling; update the method signature
and delete the unused parameter reference accordingly.
There was a problem hiding this comment.
and move to component decorator any host related stuff
There was a problem hiding this comment.
@mikij, absolutely! Per the coding guidelines that flag @HostListener, let's move the event binding to the @Component decorator's host property. Combined with the earlier suggestion to drop the dead focus/blur listeners, here's the complete refactor:
In the @Component decorator, add:
@Component({
selector: 'zard-float-label',
standalone: true,
template: `<ng-content />`,
encapsulation: ViewEncapsulation.None,
host: {
'(input)': 'onInput()'
},
styles: `...`
})Then remove the @HostListener decorators and simplify the method:
- @HostListener('input', ['$event'])
- @HostListener('focus', ['$event'])
- @HostListener('blur', ['$event'])
- onInteraction(event: Event) {
- this.updateLabelState();
- }
+ onInput() {
+ this.updateLabelState();
+ }This keeps focus handling entirely in CSS (:has(...:focus)) while moving the input listener to the declarative host binding—cleaner and aligned with the project's Angular patterns.
✏️ Learnings added
Learnt from: mikij
Repo: zard-ui/zardui PR: 326
File: libs/zard/src/lib/components/input/float.label.component.ts:71-0
Timestamp: 2025-11-14T22:52:09.094Z
Learning: In libs/zard/src/lib/components/*/*.component.ts files, move HostListener and HostBinding to the Component decorator's host property instead of using decorators on class members (e.g., host: { '(input)': 'onInput()' }).
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Component selector should follow: 'z-[name], [z-[name]]' (element and attribute selectors)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Use signal-based inputs via input() for public inputs (e.g., variant, size, class)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use signal-based inputs via input() for component inputs (e.g., variant, size, class)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Bind host class to computed classes via host: { '[class]': 'classes()' }
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Host-bind the class attribute and compute classes via computed() + mergeClasses(CVA(...), class)
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-10-17T17:12:22.571Z
Learning: Applies to libs/blocks/src/lib/*/*.component.{ts,html} : Use ZardUI form components for validation (FormField, FormLabel, FormControl) in blocks with forms
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Provide a selector in the form 'z-[name], [z-[name]]' for each component
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to apps/web/src/app/shared/constants/components.constant.ts : Update the component registry when adding components to ensure docs/demo rendering
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Place each Angular component in its own folder and name the main file [name].component.ts under libs/zard/src/lib/components/[name]/
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from libs/zard/src/lib/components/components.ts
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Use Tailwind utility classes and resolve class conflicts via tailwind-merge (through mergeClasses) in components
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use ChangeDetectionStrategy.OnPush for all Angular components
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from the barrel file libs/zard/src/lib/components/components.ts
|
|
||
| @Component({ | ||
| selector: 'z-demo-input-float-input', | ||
| standalone: true, |
There was a problem hiding this comment.
remove standalone as it is true by default
mikij
left a comment
There was a problem hiding this comment.
what are the changes in the lock file?
ribeiromatheuss
left a comment
There was a problem hiding this comment.
need include tests
ribeiromatheuss
left a comment
There was a problem hiding this comment.
I believe this component should be part of the forms component in a separate file
There was a problem hiding this comment.
Change the filename to float-label
There was a problem hiding this comment.
Change the filename to float-label.component.ts
There was a problem hiding this comment.
Actionable comments posted: 5
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/components/select/select.component.ts (2)
200-205: Prefer explicitfromEvent/renderer.listenover@HostListener('document:click')Given the project’s move away from
@HostListener, it would be more in line with current patterns to replace thedocument:clickHostListener with an RxJS/Renderer2 subscription that you attach conditionally inngOnInit/ngAfterViewInit(behindisPlatformBrowser(this.platformId)) and tear down via the existingSubscriptioninngOnDestroy. This also centralizes cleanup in one place.Not blocking, but worth aligning with the newer event-handling approach used elsewhere in the library.
161-167: Keepinput-has-valuein sync whenzValueorwriteValuechangesThe new
updateSelectStatewiring (formvalueChanges, focus/blur, and initial call inngAfterContentInit) correctly tracks form-driven changes, but pure@Input() zValuechanges after initialization and calls towriteValuewon't automatically toggleinput-has-value.selectedValuewill update due to its computed dependency, yetupdateSelectStateis never invoked for those changes.To keep float-label behavior consistent:
- Call
this.updateSelectState()fromwriteValue(line 347) and add an effect onzValue()to sync the class whenever either changes.- Or create a single side-effect that reacts to
selectedValue()changes and callsupdateSelectState(guarding against SSR if needed).Also, refactor
updateSelectStatefrom a private arrow property (line 318) to a private method—arrow properties create per-instance allocations and don't follow Angular conventions. Replaceprivate updateSelectState = () => { ... }withprivate updateSelectState(): void { ... }.Additionally, move the
@HostListener('document:click')decorator (line 201) to use a subscription-based approach withfromEvent+Renderer2.listen()+ platform guard, consistent with your existing pattern for button focus/blur events and aligned with framework guidelines.libs/zard/src/lib/components/input/input.directive.ts (1)
17-73: Input state wiring looks solid; tightenupdateInputStatevisibilityThe new form/DOM subscriptions and
Renderer2usage correctly keepinput-has-valueanddata-statusin sync, and teardown viaSubscriptioninngOnDestroyis good.Since
updateInputStateis only called internally, consider:
- Making it
private, and- Defining it as a regular method (
private updateInputState(): void { ... }) instead of a public arrow property, to avoid unintentionally exposing it on the directive’s public surface and to reduce per-instance allocations.Behavior doesn’t change, but the API surface stays slimmer.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (16)
apps/web/public/components/float-label/demo/borderless.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/demo/default.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/demo/float.input.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/demo/input.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/demo/select.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/demo/size.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/demo/status.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/demo/text-area.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/demo/textarea.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/doc/api.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/float-label/doc/overview.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/components/input/demo/float.input.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/installation/cli/add-float-label.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/installation/manual/float-label.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/installation/manual/input.mdis excluded by!apps/web/public/**and included byapps/**apps/web/public/installation/manual/select.mdis excluded by!apps/web/public/**and included byapps/**
📒 Files selected for processing (15)
apps/web/prerender-routes.txt(1 hunks)apps/web/src/app/shared/constants/routes.constant.ts(1 hunks)libs/zard/src/lib/components/float-label/demo/default.ts(1 hunks)libs/zard/src/lib/components/float-label/demo/input.ts(1 hunks)libs/zard/src/lib/components/float-label/demo/select.ts(1 hunks)libs/zard/src/lib/components/float-label/demo/status.ts(1 hunks)libs/zard/src/lib/components/float-label/demo/text-area.ts(1 hunks)libs/zard/src/lib/components/float-label/doc/api.md(1 hunks)libs/zard/src/lib/components/float-label/doc/overview.md(1 hunks)libs/zard/src/lib/components/float-label/float.label.component.ts(1 hunks)libs/zard/src/lib/components/float-label/float.label.spec.ts(1 hunks)libs/zard/src/lib/components/float-label/float.label.variants.ts(1 hunks)libs/zard/src/lib/components/input/demo/input.ts(1 hunks)libs/zard/src/lib/components/input/input.directive.ts(2 hunks)libs/zard/src/lib/components/select/select.component.ts(7 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
libs/zard/src/lib/components/**/demo/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Place demo files under a demo/ directory (including a main demo export file, default.ts, and variant example files)
Files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.ts
libs/zard/src/lib/components/**/doc/{overview,api}.md
📄 CodeRabbit inference engine (CLAUDE.md)
Provide documentation files overview.md and api.md under each component's doc/ directory
Files:
libs/zard/src/lib/components/float-label/doc/api.mdlibs/zard/src/lib/components/float-label/doc/overview.md
libs/zard/src/lib/components/*/doc/api.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Provide documentation: doc/api.md for complete API reference (props, events, methods)
Files:
libs/zard/src/lib/components/float-label/doc/api.md
libs/zard/src/lib/components/**/*.variants.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Define styling variants with Class Variance Authority (CVA) in a companion .variants.ts file
Files:
libs/zard/src/lib/components/float-label/float.label.variants.ts
libs/zard/src/lib/components/**/*.{component,variants}.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use tailwind-merge for class merging and clsx for conditional classes when composing CSS classes
Files:
libs/zard/src/lib/components/float-label/float.label.variants.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/select/select.component.ts
libs/zard/src/lib/components/*/*.variants.ts
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Define component variants with CVA in a dedicated [name].variants.ts file and export typed variants
Files:
libs/zard/src/lib/components/float-label/float.label.variants.ts
libs/zard/src/lib/components/**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Co-locate unit tests next to components using .spec.ts filenames
Files:
libs/zard/src/lib/components/float-label/float.label.spec.ts
libs/zard/src/lib/components/*/*.spec.ts
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Co-locate Jest tests next to components in [name].spec.ts using Angular Testing Utilities and @happy-dom/jest-environment
Files:
libs/zard/src/lib/components/float-label/float.label.spec.ts
libs/zard/src/lib/components/**/*.component.ts
📄 CodeRabbit inference engine (CLAUDE.md)
libs/zard/src/lib/components/**/*.component.ts: Angular components must be standalone (standalone: true)
Use ChangeDetectionStrategy.OnPush for all Angular components
Bind host class to computed classes via host: { '[class]': 'classes()' }
Use signal-based inputs via input() for component inputs (e.g., variant, size, class)
Provide a selector in the form 'z-[name], [z-[name]]' for each component
Files:
libs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/select/select.component.ts
libs/zard/src/lib/components/*/*.component.ts
📄 CodeRabbit inference engine (CONTRIBUTING.md)
libs/zard/src/lib/components/*/*.component.ts: Place each Angular component in its own folder and name the main file [name].component.ts under libs/zard/src/lib/components/[name]/
Components must be standalone (standalone: true) and use ChangeDetectionStrategy.OnPush
Component selector should follow: 'z-[name], [z-[name]]' (element and attribute selectors)
Use signal-based inputs via input() for public inputs (e.g., variant, size, class)
Host-bind the class attribute and compute classes via computed() + mergeClasses(CVA(...), class)
Use Tailwind utility classes and resolve class conflicts via tailwind-merge (through mergeClasses) in components
Files:
libs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/select/select.component.ts
libs/zard/src/lib/components/*/doc/overview.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Provide documentation: doc/overview.md for overview, use cases, and basic examples
Files:
libs/zard/src/lib/components/float-label/doc/overview.md
libs/zard/src/lib/components/*/demo/default.ts
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Each component must provide a demo/default.ts exporting a DefaultExample with name, code, and lazy-loaded component
Files:
libs/zard/src/lib/components/float-label/demo/default.ts
🧠 Learnings (34)
📓 Common learnings
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-10-17T17:12:22.571Z
Learning: Applies to libs/blocks/src/lib/*/*.component.{ts,html} : Use ZardUI form components for validation (FormField, FormLabel, FormControl) in blocks with forms
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/demo/**/*.ts : Place demo files under a demo/ directory (including a main demo export file, default.ts, and variant example files)
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/demo/default.ts : Each component must provide a demo/default.ts exporting a DefaultExample with name, code, and lazy-loaded component
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Use signal-based inputs via input() for public inputs (e.g., variant, size, class)
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use signal-based inputs via input() for component inputs (e.g., variant, size, class)
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from libs/zard/src/lib/components/components.ts
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-11-10T21:46:33.213Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 318
File: libs/zard/src/lib/components/select/demo/default.ts:21-21
Timestamp: 2025-11-10T21:46:33.213Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, intentionally showing different patterns (e.g., primitive values vs signals) across different demos is valuable for demonstrating the flexibility of Angular features like two-way binding.
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-11-04T20:46:01.373Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 309
File: libs/zard/src/lib/components/select/demo/multi-select.ts:23-27
Timestamp: 2025-11-04T20:46:01.373Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, console.log statements are acceptable and often intentional to demonstrate reactivity and help users understand how the component works.
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from the barrel file libs/zard/src/lib/components/components.ts
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-17T17:12:22.571Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-10-17T17:12:22.571Z
Learning: Applies to libs/blocks/src/lib/*/*.component.{ts,html} : Use ZardUI form components for validation (FormField, FormLabel, FormControl) in blocks with forms
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tsapps/web/prerender-routes.txtlibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to apps/web/src/app/shared/constants/components.constant.ts : Update the component registry when adding components to ensure docs/demo rendering
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tsapps/web/src/app/shared/constants/routes.constant.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Provide a selector in the form 'z-[name], [z-[name]]' for each component
Applied to files:
libs/zard/src/lib/components/float-label/demo/input.tslibs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/doc/api.mdlibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Component selector should follow: 'z-[name], [z-[name]]' (element and attribute selectors)
Applied to files:
libs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/doc/api.mdlibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Place each Angular component in its own folder and name the main file [name].component.ts under libs/zard/src/lib/components/[name]/
Applied to files:
libs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.spec.ts : Co-locate Jest tests next to components in [name].spec.ts using Angular Testing Utilities and happy-dom/jest-environment
Applied to files:
libs/zard/src/lib/components/float-label/demo/select.tslibs/zard/src/lib/components/float-label/float.label.spec.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/doc/api.md : Provide documentation: doc/api.md for complete API reference (props, events, methods)
Applied to files:
libs/zard/src/lib/components/float-label/doc/api.mdlibs/zard/src/lib/components/float-label/doc/overview.md
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/doc/{overview,api}.md : Provide documentation files overview.md and api.md under each component's doc/ directory
Applied to files:
libs/zard/src/lib/components/float-label/doc/api.mdlibs/zard/src/lib/components/float-label/doc/overview.md
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/doc/overview.md : Provide documentation: doc/overview.md for overview, use cases, and basic examples
Applied to files:
libs/zard/src/lib/components/float-label/doc/api.mdlibs/zard/src/lib/components/float-label/doc/overview.md
📚 Learning: 2025-11-04T10:18:55.477Z
Learnt from: mihajm
Repo: zard-ui/zardui PR: 308
File: libs/zard/src/lib/components/button-group/doc/overview.md:1-3
Timestamp: 2025-11-04T10:18:55.477Z
Learning: In zardui repo, doc/overview.md files for components should contain only a brief overview description. Examples are provided through separate demo files and the api.md documentation, not in overview.md.
Applied to files:
libs/zard/src/lib/components/float-label/doc/api.mdlibs/zard/src/lib/components/float-label/doc/overview.md
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.variants.ts : Define styling variants with Class Variance Authority (CVA) in a companion <name>.variants.ts file
Applied to files:
libs/zard/src/lib/components/float-label/float.label.variants.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.variants.ts : Define component variants with CVA in a dedicated [name].variants.ts file and export typed variants
Applied to files:
libs/zard/src/lib/components/float-label/float.label.variants.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Use Tailwind utility classes and resolve class conflicts via tailwind-merge (through mergeClasses) in components
Applied to files:
libs/zard/src/lib/components/float-label/float.label.variants.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.{component,variants}.ts : Use tailwind-merge for class merging and clsx for conditional classes when composing CSS classes
Applied to files:
libs/zard/src/lib/components/float-label/float.label.variants.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-15T00:53:17.826Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: packages/cli/README.md:0-0
Timestamp: 2025-10-15T00:53:17.826Z
Learning: Applies to packages/cli/**/components.json : Keep ZardUI CLI configuration in components.json (style, tailwind.css path, baseColor, cssVariables, aliases)
Applied to files:
libs/zard/src/lib/components/float-label/float.label.variants.ts
📚 Learning: 2025-11-14T22:52:09.094Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 326
File: libs/zard/src/lib/components/input/float.label.component.ts:71-0
Timestamp: 2025-11-14T22:52:09.094Z
Learning: In libs/zard/src/lib/components/*/*.component.ts files, move HostListener and HostBinding to the Component decorator's host property instead of using decorators on class members (e.g., host: { '(input)': 'onInput()' }).
Applied to files:
libs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-17T17:12:22.571Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-10-17T17:12:22.571Z
Learning: Applies to libs/blocks/src/lib/*/*.component.ts : Use ReactiveFormsModule for form handling in block components that include forms
Applied to files:
libs/zard/src/lib/components/float-label/demo/status.tslibs/zard/src/lib/components/float-label/demo/text-area.tslibs/zard/src/lib/components/float-label/demo/default.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to apps/web/public/components/*/{demo,doc}/** : Demo and doc files in apps/web/public/components/*/{demo,doc} are synchronized outputs; source of truth lives under libs/zard/src/lib/components/*/{demo,doc}
Applied to files:
apps/web/prerender-routes.txt
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.spec.ts : Co-locate unit tests next to components using .spec.ts filenames
Applied to files:
libs/zard/src/lib/components/float-label/float.label.spec.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Bind host class to computed classes via host: { '[class]': 'classes()' }
Applied to files:
libs/zard/src/lib/components/float-label/float.label.spec.tslibs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-17T19:24:10.610Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-17T19:24:10.610Z
Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Host-bind the class attribute and compute classes via computed() + mergeClasses(CVA(...), class)
Applied to files:
libs/zard/src/lib/components/float-label/float.label.component.tslibs/zard/src/lib/components/input/input.directive.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use ChangeDetectionStrategy.OnPush for all Angular components
Applied to files:
libs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-15T00:51:30.882Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-15T00:51:30.882Z
Learning: Applies to libs/zard/src/index.ts : Maintain the library public entry point in libs/zard/src/index.ts
Applied to files:
libs/zard/src/lib/components/input/input.directive.tslibs/zard/src/lib/components/input/demo/input.ts
📚 Learning: 2025-10-31T10:03:18.563Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 299
File: libs/zard/src/lib/components/select/select.component.ts:34-38
Timestamp: 2025-10-31T10:03:18.563Z
Learning: In Angular 19+ (including Angular 20 used in this project), components are standalone by default. The `standalone: true` flag is redundant and should be omitted unless explicitly setting `standalone: false` to opt out.
Applied to files:
libs/zard/src/lib/components/select/select.component.ts
📚 Learning: 2025-10-15T00:53:17.826Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: packages/cli/README.md:0-0
Timestamp: 2025-10-15T00:53:17.826Z
Learning: Applies to packages/cli/src/app/shared/components/**/*.{ts,html,css} : Place shared Angular UI components under src/app/shared/components
Applied to files:
apps/web/src/app/shared/constants/routes.constant.ts
🧬 Code graph analysis (6)
libs/zard/src/lib/components/float-label/demo/select.ts (2)
libs/zard/src/lib/components/float-label/float.label.component.ts (1)
Component(7-44)libs/zard/src/lib/components/select/select.component.ts (1)
Component(38-496)
libs/zard/src/lib/components/float-label/demo/status.ts (1)
libs/zard/src/lib/components/float-label/float.label.component.ts (1)
Component(7-44)
libs/zard/src/lib/components/float-label/float.label.component.ts (7)
libs/zard/src/lib/components/float-label/demo/default.ts (1)
Component(8-26)libs/zard/src/lib/components/float-label/demo/select.ts (1)
Component(8-22)libs/zard/src/lib/components/float-label/demo/status.ts (1)
Component(9-31)libs/zard/src/lib/components/float-label/demo/text-area.ts (1)
Component(8-26)libs/zard/src/lib/components/select/select.component.ts (1)
Component(38-496)libs/zard/src/lib/shared/utils/utils.ts (1)
mergeClasses(4-6)libs/zard/src/lib/components/float-label/float.label.variants.ts (1)
floatLabelStyles(3-66)
libs/zard/src/lib/components/input/input.directive.ts (2)
libs/zard/src/lib/components/menu/menu-item.directive.ts (1)
Directive(10-85)libs/zard/src/lib/components/menu/menu-content.directive.ts (1)
Directive(9-21)
libs/zard/src/lib/components/float-label/demo/text-area.ts (2)
libs/zard/src/lib/components/float-label/demo/default.ts (1)
Component(8-26)libs/zard/src/lib/components/float-label/float.label.component.ts (1)
Component(7-44)
libs/zard/src/lib/components/float-label/demo/default.ts (2)
libs/zard/src/lib/components/float-label/demo/text-area.ts (1)
Component(8-26)libs/zard/src/lib/components/float-label/float.label.component.ts (1)
Component(7-44)
🪛 markdownlint-cli2 (0.18.1)
libs/zard/src/lib/components/float-label/doc/api.md
3-3: Files should end with a single newline character
(MD047, single-trailing-newline)
libs/zard/src/lib/components/float-label/doc/overview.md
3-3: Files should end with a single newline character
(MD047, single-trailing-newline)
🔇 Additional comments (9)
libs/zard/src/lib/components/input/demo/input.ts (1)
4-5: Import reorder is fineSwapping the
statusandtext-areaimports does not affect behavior; the INPUT examples remain unchanged.apps/web/prerender-routes.txt (1)
30-30: Float Label prerender route wired correctly
/docs/components/float-labelmatches the components route path and is placed consistently alongside other component docs routes.apps/web/src/app/shared/constants/routes.constant.ts (1)
49-49: Component sidebar entry for Float Label is consistentThe new
{ name: 'Float Label', path: '/docs/components/float-label', available: true }entry aligns with the docs path and will sort correctly among other components.libs/zard/src/lib/components/float-label/demo/input.ts (1)
1-32: FLOAT_LABEL demo metadata is coherent and wired to all variantsThe FLOAT_LABEL config correctly wires the default, textarea, select, and status demo components with a consistent slug (
componentName: 'float-label') and column layout, matching the new docs route.libs/zard/src/lib/components/float-label/demo/status.ts (1)
1-31: Mark the status demo as standalone and use OnPush change detectionThis demo also uses the
importsarray, so it must be a standalone component, and it should follow the library’s Angular best practices.
- Blocking: Add
standalone: trueso Angular treats this as a standalone component; otherwise theimportsconfig is invalid.- Best practice: Use
ChangeDetectionStrategy.OnPushfor consistency with other Zard UI components and demos.Suggested change:
-import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; @@ -@Component({ - selector: 'z-demo-float-label-status', - imports: [ReactiveFormsModule, ZardInputDirective, ZardFloatLabelComponent, ZardFormLabelComponent], +@Component({ + standalone: true, + selector: 'z-demo-float-label-status', + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ReactiveFormsModule, ZardInputDirective, ZardFloatLabelComponent, ZardFormLabelComponent], @@ }) export class ZardDemoFloatLabelStatusComponent {}⛔ Skipped due to learnings
Learnt from: CR Repo: zard-ui/zardui PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-10-15T00:51:30.882Z Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use ChangeDetectionStrategy.OnPush for all Angular componentsLearnt from: mikij Repo: zard-ui/zardui PR: 299 File: libs/zard/src/lib/components/select/select.component.ts:34-38 Timestamp: 2025-10-31T10:03:18.563Z Learning: In Angular 19+ (including Angular 20 used in this project), components are standalone by default. The `standalone: true` flag is redundant and should be omitted unless explicitly setting `standalone: false` to opt out.Learnt from: mikij Repo: zard-ui/zardui PR: 326 File: libs/zard/src/lib/components/input/float.label.component.ts:71-0 Timestamp: 2025-11-14T22:52:09.094Z Learning: In libs/zard/src/lib/components/*/*.component.ts files, move HostListener and HostBinding to the Component decorator's host property instead of using decorators on class members (e.g., host: { '(input)': 'onInput()' }).Learnt from: mikij Repo: zard-ui/zardui PR: 318 File: libs/zard/src/lib/components/select/demo/default.ts:21-21 Timestamp: 2025-11-10T21:46:33.213Z Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, intentionally showing different patterns (e.g., primitive values vs signals) across different demos is valuable for demonstrating the flexibility of Angular features like two-way binding.Learnt from: mikij Repo: zard-ui/zardui PR: 309 File: libs/zard/src/lib/components/select/demo/multi-select.ts:23-27 Timestamp: 2025-11-04T20:46:01.373Z Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, console.log statements are acceptable and often intentional to demonstrate reactivity and help users understand how the component works.Learnt from: CR Repo: zard-ui/zardui PR: 0 File: libs/blocks/README.md:0-0 Timestamp: 2025-10-17T17:12:22.571Z Learning: Applies to libs/blocks/src/lib/*/*.component.{ts,html} : Use ZardUI form components for validation (FormField, FormLabel, FormControl) in blocks with formsLearnt from: CR Repo: zard-ui/zardui PR: 0 File: CONTRIBUTING.md:0-0 Timestamp: 2025-10-17T19:24:10.610Z Learning: Applies to libs/zard/src/lib/components/*/*.component.ts : Component selector should follow: 'z-[name], [z-[name]]' (element and attribute selectors)Learnt from: CR Repo: zard-ui/zardui PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-10-15T00:51:30.882Z Learning: Applies to libs/zard/src/lib/components/**/demo/**/*.ts : Place demo files under a demo/ directory (including a main demo export file, default.ts, and variant example files)Learnt from: CR Repo: zard-ui/zardui PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-10-15T00:51:30.882Z Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Provide a selector in the form 'z-[name], [z-[name]]' for each componentLearnt from: CR Repo: zard-ui/zardui PR: 0 File: CONTRIBUTING.md:0-0 Timestamp: 2025-10-17T19:24:10.610Z Learning: Applies to libs/zard/src/lib/components/*/demo/default.ts : Each component must provide a demo/default.ts exporting a DefaultExample with name, code, and lazy-loaded componentLearnt from: CR Repo: zard-ui/zardui PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-10-15T00:51:30.882Z Learning: Applies to libs/zard/src/lib/components/components.ts : Export new components from libs/zard/src/lib/components/components.tsLearnt from: CR Repo: zard-ui/zardui PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-10-15T00:51:30.882Z Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use signal-based inputs via input() for component inputs (e.g., variant, size, class)libs/zard/src/lib/components/float-label/demo/text-area.ts (1)
1-26: LGTM! Clean demo implementation.The textarea demo follows established patterns, properly integrates reactive forms, and demonstrates error state handling with the float label component.
libs/zard/src/lib/components/float-label/float.label.variants.ts (1)
1-66: LGTM! Comprehensive CVA styling configuration.The variants properly leverage CVA and Tailwind utilities with CSS
:has()selectors to handle all float label states (focus, value, status) declaratively. This aligns perfectly with the PR objectives.libs/zard/src/lib/components/float-label/demo/default.ts (1)
1-26: LGTM! Standard default demo pattern.The default demo correctly demonstrates the float label component with reactive forms and validation state handling.
libs/zard/src/lib/components/float-label/float.label.spec.ts (1)
1-207: LGTM! Excellent test coverage.The test suite comprehensively covers all component behaviors including focus/value states, SSR guards, dynamic class toggling, status styling, and event-driven updates. Well-structured and thorough.
| import { Component } from '@angular/core'; | ||
|
|
||
| import { ZardFormLabelComponent } from '../../form/form.component'; | ||
| import { ZardSelectItemComponent } from '../../select/select-item.component'; | ||
| import { ZardSelectComponent } from '../../select/select.component'; | ||
| import { ZardFloatLabelComponent } from '../float.label.component'; | ||
|
|
||
| @Component({ | ||
| selector: 'z-demo-float-label-select', | ||
| imports: [ZardFloatLabelComponent, ZardFormLabelComponent, ZardSelectComponent, ZardSelectItemComponent], | ||
| template: ` | ||
| <z-float-label> | ||
| <z-select value="react" class="w-[200px]" zSize="lg"> | ||
| <z-select-item zValue="angular">Angular</z-select-item> | ||
| <z-select-item zValue="react">React</z-select-item> | ||
| <z-select-item zValue="vue">Vue</z-select-item> | ||
| </z-select> | ||
| <label z-form-label>Framework</label> | ||
| </z-float-label> | ||
| `, | ||
| }) | ||
| export class ZardDemoFloatLabelSelectComponent {} |
There was a problem hiding this comment.
Make the select demo a proper standalone, OnPush component and fix the initial value
Two things here:
-
Missing
standalone: true(blocking)
You’re using theimportsarray on the component, which only works for standalone components. Withoutstandalone: true, this will not compile correctly under Angular’s standalone model. -
Angular best practices for demos
To keep demos aligned with the rest of the library, this component should also opt intoChangeDetectionStrategy.OnPush. -
Select API: use
zValueinstead ofvalue
ZardSelectComponentexposes azValueinput / CVA rather than avalueinput. Usingvalue="react"won’t initialize the selected option as intended, so the demo won’t show "React" pre‑selected.
Suggested change:
-import { Component } from '@angular/core';
+import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
- selector: 'z-demo-float-label-select',
- imports: [ZardFloatLabelComponent, ZardFormLabelComponent, ZardSelectComponent, ZardSelectItemComponent],
+ standalone: true,
+ selector: 'z-demo-float-label-select',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ imports: [ZardFloatLabelComponent, ZardFormLabelComponent, ZardSelectComponent, ZardSelectItemComponent],
template: `
<z-float-label>
- <z-select value="react" class="w-[200px]" zSize="lg">
+ <z-select zValue="react" class="w-[200px]" zSize="lg">
<z-select-item zValue="angular">Angular</z-select-item>
<z-select-item zValue="react">React</z-select-item>
<z-select-item zValue="vue">Vue</z-select-item>
</z-select>
<label z-form-label>Framework</label>
</z-float-label>
`,
})
export class ZardDemoFloatLabelSelectComponent {}🤖 Prompt for AI Agents
In libs/zard/src/lib/components/float-label/demo/select.ts around lines 1 to 22,
the component is missing standalone: true, isn’t using
ChangeDetectionStrategy.OnPush, and uses the wrong input for the select; update
the @Component decorator to include standalone: true and changeDetection:
ChangeDetectionStrategy.OnPush (importing ChangeDetectionStrategy from
@angular/core), and in the template replace value="react" on <z-select> with
zValue="react" so the select initializes correctly; keep the existing imports
array as-is for the standalone component.
| ## [z-float-label] <span class="api-type-label component">Component</span> | ||
|
|
||
| > Wraps `input`, `textarea`, or `z-select` with a floating label. | ||
| > The label floats when the input has focus or contains a value. No newline at end of file |
There was a problem hiding this comment.
API doc looks correct; add trailing newline for markdownlint
The description of z-float-label is clear and consistent with the implementation. markdownlint reports MD047 though, so please add a single newline at the end of the file.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
3-3: Files should end with a single newline character
(MD047, single-trailing-newline)
🤖 Prompt for AI Agents
In libs/zard/src/lib/components/float-label/doc/api.md around lines 1 to 4, the
markdown file is missing a trailing newline which triggers markdownlint MD047;
fix it by adding a single newline character at the end of the file (ensure the
file ends with exactly one newline) and save the file.
| # Float Label | ||
|
|
||
| A wrapper component that provides a floating label animation for form inputs. No newline at end of file |
There was a problem hiding this comment.
Overview content is good; add trailing newline for markdownlint
The brief description matches the component’s purpose and the repo’s pattern for overview docs, but markdownlint flags the missing final newline (MD047). Please end the file with a single trailing newline.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
3-3: Files should end with a single newline character
(MD047, single-trailing-newline)
🤖 Prompt for AI Agents
libs/zard/src/lib/components/float-label/doc/overview.md around lines 1 to 3:
the markdown file is missing a final newline which triggers markdownlint MD047;
simply add a single trailing newline character at the end of the file (ensure
the file ends with one blank line) and save.
| @Component({ | ||
| selector: 'z-float-label', | ||
| template: `<ng-content />`, | ||
| encapsulation: ViewEncapsulation.None, | ||
| host: { | ||
| '[class]': 'classes()', | ||
| }, | ||
| }) |
There was a problem hiding this comment.
Add ChangeDetectionStrategy.OnPush.
The component is missing ChangeDetectionStrategy.OnPush, which is required by coding guidelines for all Angular components to optimize change detection.
Apply this diff:
-import { Component, ElementRef, AfterViewInit, HostListener, PLATFORM_ID, ViewEncapsulation, computed, input, inject } from '@angular/core';
+import { Component, ElementRef, AfterViewInit, HostListener, PLATFORM_ID, ViewEncapsulation, ChangeDetectionStrategy, computed, input, inject } from '@angular/core'; @Component({
selector: 'z-float-label',
template: `<ng-content />`,
encapsulation: ViewEncapsulation.None,
+ changeDetection: ChangeDetectionStrategy.OnPush,
host: {
'[class]': 'classes()',
},
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @Component({ | |
| selector: 'z-float-label', | |
| template: `<ng-content />`, | |
| encapsulation: ViewEncapsulation.None, | |
| host: { | |
| '[class]': 'classes()', | |
| }, | |
| }) | |
| @Component({ | |
| selector: 'z-float-label', | |
| template: `<ng-content />`, | |
| encapsulation: ViewEncapsulation.None, | |
| changeDetection: ChangeDetectionStrategy.OnPush, | |
| host: { | |
| '[class]': 'classes()', | |
| }, | |
| }) |
🤖 Prompt for AI Agents
In libs/zard/src/lib/components/float-label/float.label.component.ts around
lines 7 to 14, the @Component decorator lacks ChangeDetectionStrategy.OnPush;
update the decorator to add changeDetection: ChangeDetectionStrategy.OnPush and
add the corresponding import from @angular/core at the top of the file (ensure
ChangeDetectionStrategy is imported alongside Component and ViewEncapsulation).
This will set the component to use OnPush change detection without changing
template or host configuration.
| @HostListener('input') | ||
| @HostListener('focus') | ||
| @HostListener('blur') | ||
| onInteraction() { | ||
| this.updateLabelState(); | ||
| } |
There was a problem hiding this comment.
Migrate @HostListener decorators to host property.
The @HostListener decorators violate project conventions. Event listeners should be declared in the component decorator's host property instead of using decorators on class members.
Based on learnings
Apply this diff:
-import { Component, ElementRef, AfterViewInit, HostListener, PLATFORM_ID, ViewEncapsulation, computed, input, inject } from '@angular/core';
+import { Component, ElementRef, AfterViewInit, PLATFORM_ID, ViewEncapsulation, computed, input, inject } from '@angular/core'; @Component({
selector: 'z-float-label',
template: `<ng-content />`,
encapsulation: ViewEncapsulation.None,
host: {
'[class]': 'classes()',
+ '(input)': 'onInteraction()',
+ '(focus)': 'onInteraction()',
+ '(blur)': 'onInteraction()',
},
})
export class ZardFloatLabelComponent implements AfterViewInit {
readonly class = input<string>('');
private readonly el = inject(ElementRef);
private readonly platformId = inject(PLATFORM_ID);
protected readonly classes = computed(() => mergeClasses(floatLabelStyles(), this.class()));
ngAfterViewInit() {
this.updateLabelState();
}
- @HostListener('input')
- @HostListener('focus')
- @HostListener('blur')
onInteraction() {
this.updateLabelState();
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @HostListener('input') | |
| @HostListener('focus') | |
| @HostListener('blur') | |
| onInteraction() { | |
| this.updateLabelState(); | |
| } | |
| onInteraction() { | |
| this.updateLabelState(); | |
| } |
🤖 Prompt for AI Agents
In libs/zard/src/lib/components/float-label/float.label.component.ts around
lines 27-32, replace the three @HostListener decorators on onInteraction() with
host bindings in the @Component decorator: add or extend the host property to
map '(input)', '(focus)', and '(blur)' to 'onInteraction()' (e.g. '(input)':
'onInteraction()', '(focus)': 'onInteraction()', '(blur)': 'onInteraction()')
and remove the @HostListener decorators from the class method so the component
uses the host metadata for event listeners.
| this.updateLabelState(); | ||
| } | ||
|
|
||
| @HostListener('input') |
| import { floatLabelStyles } from './float.label.variants'; | ||
| import { mergeClasses } from '../../shared/utils/utils'; | ||
|
|
||
| @Component({ |




What was done? 📝
Implemented ZardFloatLabelComponent with floating label support using only CSS :has() and minimal TS logic. The label automatically floats when the input is focused or has a value, with smooth transitions and support for validation states (destructive, warning, success). Added safe SSR handling with isPlatformBrowser when accessing document.activeElement. Compatible with input, textarea, and button via ng-content (may work with select too).
Screenshots or GIFs 📸
|-----Figma-----|
|-----Implementation-----|
Link to Issue 🔗
Type of change 🏗
Breaking change 🚨
Checklist 🧐
Summary by CodeRabbit
New Features
Improvements