cats-ui-lib 2.2.5 โ†’ 2.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +780 -780
  2. package/assets/images/building-07.svg +3 -3
  3. package/assets/images/check-disabled.svg +3 -3
  4. package/assets/images/check-white.svg +3 -3
  5. package/assets/images/chevron-down-white.svg +3 -3
  6. package/assets/images/chevron-down.svg +3 -3
  7. package/assets/images/chevron-right-blue.svg +3 -3
  8. package/assets/images/chevron-right-red.svg +3 -3
  9. package/assets/images/chevron-up.svg +3 -3
  10. package/assets/images/clock-refresh.svg +3 -3
  11. package/assets/images/file-check-02.svg +3 -3
  12. package/assets/images/filled-dropdown.svg +3 -3
  13. package/assets/images/indeterminate.svg +3 -3
  14. package/assets/images/key-01.svg +3 -3
  15. package/assets/images/log-out-04.svg +3 -3
  16. package/assets/images/menu-collapsed.svg +4 -4
  17. package/assets/images/message-smile-square.svg +3 -3
  18. package/assets/images/settings-04.svg +3 -3
  19. package/assets/images/shuffle-01.svg +3 -3
  20. package/assets/images/spanish-flag.svg +72 -72
  21. package/assets/images/star-yellow.svg +3 -3
  22. package/assets/images/user-image.svg +9 -9
  23. package/assets/images/users-01.svg +3 -3
  24. package/assets/images/x-cancel-btn.svg +3 -3
  25. package/fesm2022/cats-ui-lib.mjs +153 -139
  26. package/fesm2022/cats-ui-lib.mjs.map +1 -1
  27. package/index.d.ts +2 -3
  28. package/package.json +1 -1
  29. package/styles/_fonts.scss +82 -82
  30. package/styles/_functions.scss +10 -10
  31. package/styles/_index.scss +6 -6
  32. package/styles/_mixins.scss +65 -65
  33. package/styles/_reset.scss +69 -69
  34. package/styles/_utilities.scss +894 -894
  35. package/styles/_variables.scss +126 -126
package/README.md CHANGED
@@ -1,780 +1,780 @@
1
- # cats-ui-lib
2
-
3
- A comprehensive Angular UI component library built with Angular 19, providing a rich set of reusable, customizable components for modern web applications.
4
-
5
- [![npm version](https://img.shields.io/npm/v/cats-ui-lib.svg)](https://www.npmjs.com/package/cats-ui-lib)
6
- [![Angular](https://img.shields.io/badge/Angular-19-red.svg)](https://angular.dev)
7
-
8
- ---
9
-
10
- ## ๐Ÿ“ฆ Installation
11
-
12
- ```bash
13
- npm install cats-ui-lib
14
- ```
15
-
16
- ---
17
-
18
- ## โš™๏ธ Setup
19
-
20
- ### 1. Configure `angular.json`
21
-
22
- Add the following inside the `build > options` section of your `angular.json`:
23
-
24
- ```json
25
- "assets": [
26
- {
27
- "glob": "**/*",
28
- "input": "node_modules/cats-ui-lib/assets"
29
- }
30
- ],
31
- "styles": [
32
- "node_modules/cats-ui-lib/styles/_index.scss"
33
- ]
34
- ```
35
-
36
- ---
37
-
38
- ## ๐Ÿงฉ Components
39
-
40
- ---
41
-
42
- ### `InputComponent` โ€” `<cats-ui-input>`
43
-
44
- Supports types: `text` ยท `number` ยท `email` ยท `password`
45
-
46
- **Template:**
47
-
48
- ```html
49
- <cats-ui-input [inputConfig]="inputConfig" [(ngModel)]="name" required> </cats-ui-input>
50
-
51
- <!-- Disabled state -->
52
- <cats-ui-input [disabled]="true" [inputConfig]="inputConfig" [(ngModel)]="name"> </cats-ui-input>
53
- ```
54
-
55
- **TypeScript:**
56
-
57
- ```typescript
58
- import { InputConfig } from "cats-ui-lib";
59
-
60
- inputConfig: InputConfig = {
61
- type: "text",
62
- placeholder: "Enter value",
63
- };
64
- ```
65
-
66
- **`InputConfig` options:**
67
-
68
- | Property | Type | Description |
69
- | ------------- | -------- | ------------------------------------------------- |
70
- | `type` | `string` | Input type: `text`, `email`, `password`, `number` |
71
- | `placeholder` | `string` | Placeholder text |
72
-
73
- ---
74
-
75
- ### `SingleSelectComponent` โ€” `<cats-ui-single-select>`
76
-
77
- **Template:**
78
-
79
- ```html
80
- <cats-ui-single-select [optionList]="options" [singleSelectConfig]="singleConfig" [parentNativeElement]="'parent'" (onSelection)="onSelection($event)"> </cats-ui-single-select>
81
- ```
82
-
83
- **TypeScript:**
84
-
85
- ```typescript
86
- import { SingleSelectConfig } from 'cats-ui-lib';
87
-
88
- options = [
89
- { id: 1, name: 'Option 1', disable: false },
90
- { id: 2, name: 'Option 2', disable: false },
91
- ];
92
-
93
- singleConfig: SingleSelectConfig = {
94
- idField: 'id',
95
- textField: 'name',
96
- disabledField: 'disable',
97
- placeholder: 'Select Option',
98
- };
99
-
100
- onSelection(dt: any) {
101
- console.log('Selected:', dt);
102
- }
103
- ```
104
-
105
- **`SingleSelectConfig` options:**
106
-
107
- | Property | Type | Description |
108
- | --------------- | -------- | ------------------------------ |
109
- | `idField` | `string` | Key for option ID |
110
- | `textField` | `string` | Key for display label |
111
- | `disabledField` | `string` | Key to mark option as disabled |
112
- | `placeholder` | `string` | Placeholder text |
113
-
114
- ---
115
-
116
- ### `MultiSelectComponent` โ€” `<cats-ui-multi-select>`
117
-
118
- **Template:**
119
-
120
- ```html
121
- <cats-ui-multi-select [optionList]="options" [multiSelectConfig]="multiSelectConfig" (onSelection)="onSelection($event)"> </cats-ui-multi-select>
122
- ```
123
-
124
- **TypeScript:**
125
-
126
- ```typescript
127
- import { MultiSelectConfig } from "cats-ui-lib";
128
-
129
- multiSelectConfig: MultiSelectConfig = {
130
- idField: "id",
131
- textField: "name",
132
- disabledField: "disable",
133
- placeholder: "Select Option",
134
- prefixLabel: "",
135
- enableSearch: true,
136
- chipLimit: 2,
137
- selectAll: true,
138
- required: false,
139
- };
140
- ```
141
-
142
- **`MultiSelectConfig` options:**
143
-
144
- | Property | Type | Description |
145
- | --------------- | --------- | ---------------------------------------- |
146
- | `idField` | `string` | Key for option ID |
147
- | `textField` | `string` | Key for display label |
148
- | `disabledField` | `string` | Key to mark option as disabled |
149
- | `placeholder` | `string` | Placeholder text |
150
- | `prefixLabel` | `string` | Label prefix shown before selected chips |
151
- | `enableSearch` | `boolean` | Show search input inside dropdown |
152
- | `chipLimit` | `number` | Max chips to display before `+N more` |
153
- | `selectAll` | `boolean` | Show "Select All" option |
154
- | `required` | `boolean` | Mark field as required |
155
-
156
- ---
157
-
158
- ### `AutoComplete SingleSelect` โ€” `<cats-ui-input-single-select>`
159
-
160
- **Template:**
161
-
162
- ```html
163
- <cats-ui-input-single-select [optionsList]="options" [autoSingleSelectConfig]="autoSingleSelectConfig" (onItemSelection)="onSelection($event)"> </cats-ui-input-single-select>
164
- ```
165
-
166
- **TypeScript:**
167
-
168
- ```typescript
169
- import { AutoCompleteSingleSelectConfig } from "cats-ui-lib";
170
-
171
- autoSingleSelectConfig: AutoCompleteSingleSelectConfig = {
172
- idField: "id",
173
- textField: "name",
174
- disabledField: "",
175
- placeholder: "Enter or select",
176
- required: false,
177
- customInput: true,
178
- };
179
- ```
180
-
181
- **`AutoCompleteSingleSelectConfig` options:**
182
-
183
- | Property | Type | Description |
184
- | --------------- | --------- | ---------------------------------------- |
185
- | `idField` | `string` | Key for option ID |
186
- | `textField` | `string` | Key for display label |
187
- | `disabledField` | `string` | Key to mark option as disabled |
188
- | `placeholder` | `string` | Placeholder text |
189
- | `required` | `boolean` | Mark field as required |
190
- | `customInput` | `boolean` | Allow free-text input not in option list |
191
-
192
- ---
193
-
194
- ### `AutoComplete MultiSelect` โ€” `<cats-ui-input-multi-select>`
195
-
196
- **Template:**
197
-
198
- ```html
199
- <cats-ui-input-multi-select [optionsList]="options" [autoCompleteMultiSelectConfig]="autoMultiSelectConfig" (onItemSelection)="onSelection($event)"> </cats-ui-input-multi-select>
200
- ```
201
-
202
- **TypeScript:**
203
-
204
- ```typescript
205
- import { AutoCompleteMultiSelectConfig } from "cats-ui-lib";
206
-
207
- autoMultiSelectConfig: AutoCompleteMultiSelectConfig = {
208
- idField: "id",
209
- textField: "name",
210
- disabledField: "disable",
211
- placeholder: "Type to Search",
212
- selectAll: false,
213
- chipLimit: 2,
214
- customInput: false,
215
- infoText: "Select any 8 KPIs",
216
- selectionLimit: 5,
217
- };
218
- ```
219
-
220
- **`AutoCompleteMultiSelectConfig` options:**
221
-
222
- | Property | Type | Description |
223
- | ---------------- | --------- | ---------------------------------------- |
224
- | `idField` | `string` | Key for option ID |
225
- | `textField` | `string` | Key for display label |
226
- | `disabledField` | `string` | Key to mark option as disabled |
227
- | `placeholder` | `string` | Placeholder text (supports HTML) |
228
- | `selectAll` | `boolean` | Show "Select All" option |
229
- | `chipLimit` | `number` | Max chips shown before `+N more` |
230
- | `customInput` | `boolean` | Allow free-text input |
231
- | `infoText` | `string` | Helper text shown below the input |
232
- | `selectionLimit` | `number` | Max number of items that can be selected |
233
-
234
- ---
235
-
236
- ### `SearchBoxComponent` โ€” `<cats-ui-search-box>`
237
-
238
- **Template:**
239
-
240
- ```html
241
- <cats-ui-search-box [searchConfig]="searchConfig" (searchParamValue)="searchParamValue($event)"> </cats-ui-search-box>
242
- ```
243
-
244
- **TypeScript:**
245
-
246
- ```typescript
247
- import { SearchConfig } from 'cats-ui-lib';
248
-
249
- searchConfig: SearchConfig = {
250
- serachValue: '',
251
- placeholder: 'Search Here',
252
- };
253
-
254
- searchParamValue(data: any) {
255
- console.log('searchParamValue', data);
256
- }
257
- ```
258
-
259
- ---
260
-
261
- ### `AccordionComponent` โ€” `<cats-ui-accordion>`
262
-
263
- **Template:**
264
-
265
- ```html
266
- <cats-ui-accordion>
267
- <cats-ui-accordion-item title="Panel 1" [index]="0">
268
- <ng-template>
269
- <p>Content for Panel 1.</p>
270
- </ng-template>
271
- </cats-ui-accordion-item>
272
-
273
- <cats-ui-accordion-item title="Panel 2" [index]="1">
274
- <ng-template>
275
- <p>Content for Panel 2.</p>
276
- </ng-template>
277
- </cats-ui-accordion-item>
278
- </cats-ui-accordion>
279
- ```
280
-
281
- ---
282
-
283
- ### `RadioButtonComponent` โ€” `<cats-ui-radio-button>`
284
-
285
- **Template:**
286
-
287
- ```html
288
- <cats-ui-radio-button [config]="radioConfig" [optionList]="options" (selectionChange)="onRadio($event)"> </cats-ui-radio-button>
289
- ```
290
-
291
- **TypeScript:**
292
-
293
- ```typescript
294
- import { RadioButtonConfig } from 'cats-ui-lib';
295
-
296
- radioConfig: RadioButtonConfig = {
297
- valueField: 'id',
298
- textField: 'name',
299
- name: 'gender',
300
- disabled: 'disable',
301
- };
302
-
303
- options = [
304
- { id: 1, name: 'Option 1', disable: false },
305
- { id: 2, name: 'Option 2', disable: false },
306
- ];
307
-
308
- onRadio(data: any) {
309
- console.log('radio', data);
310
- }
311
- ```
312
-
313
- **`RadioButtonConfig` options:**
314
-
315
- | Property | Type | Description |
316
- | ------------ | -------- | --------------------------------- |
317
- | `valueField` | `string` | Key for option value |
318
- | `textField` | `string` | Key for display label |
319
- | `name` | `string` | HTML radio group name |
320
- | `disabled` | `string` | Key to mark an option as disabled |
321
-
322
- ---
323
-
324
- ### `CheckboxComponent` โ€” `<cats-ui-checkbox-button>`
325
-
326
- **Template:**
327
-
328
- ```html
329
- <cats-ui-checkbox-button [checkBoxConfig]="checkBoxConfig" [optionList]="taskOptions" (onCheckBoxSelection)="checkBox($event)"> </cats-ui-checkbox-button>
330
- ```
331
-
332
- **TypeScript:**
333
-
334
- ```typescript
335
- import { CheckBoxConfig } from 'cats-ui-lib';
336
-
337
- checkBoxConfig: CheckBoxConfig = {
338
- idField: 'id',
339
- textField: 'name',
340
- name: 'check23',
341
- disabledField: 'disable',
342
- };
343
-
344
- taskOptions = [
345
- { id: '101', name: 'Parent Task 1', disable: true },
346
- { id: '102', name: 'Parent Task 2', disable: false },
347
- ];
348
-
349
- checkBox(data: any) {
350
- console.log('checkbox selection', data);
351
- }
352
- ```
353
-
354
- **`CheckBoxConfig` options:**
355
-
356
- | Property | Type | Description |
357
- | --------------- | -------- | --------------------------------- |
358
- | `idField` | `string` | Key for option ID |
359
- | `textField` | `string` | Key for display label |
360
- | `name` | `string` | HTML checkbox group name |
361
- | `disabledField` | `string` | Key to mark an option as disabled |
362
-
363
- ---
364
-
365
- ### `ToggleComponent` โ€” `<cats-ui-toogle-button>`
366
-
367
- **Template:**
368
-
369
- ```html
370
- <cats-ui-toogle-button [toggleConfig]="toggleConfig" (onToggled)="onToggled($event)"> </cats-ui-toogle-button>
371
- ```
372
-
373
- **TypeScript:**
374
-
375
- ```typescript
376
- import { ToggleConfig } from 'cats-ui-lib';
377
-
378
- toggleConfig: ToggleConfig = {
379
- disabled: false,
380
- checked: false,
381
- };
382
-
383
- onToggled(data: any) {
384
- console.log('toggled', data);
385
- }
386
- ```
387
-
388
- **`ToggleConfig` options:**
389
-
390
- | Property | Type | Description |
391
- | ---------- | --------- | --------------------- |
392
- | `disabled` | `boolean` | Disable the toggle |
393
- | `checked` | `boolean` | Initial checked state |
394
-
395
- ---
396
-
397
- ### `TabsetComponent` โ€” `<cats-ui-tabset>`
398
-
399
- An advanced tabset with add/close tab support, icons, badge counts, and a home tab.
400
-
401
- **Template:**
402
-
403
- ```html
404
- <cats-ui-tabset [tabs]="tab1" [activeTab]="activeTab" [tabConfig]="tabConfig" (tabAdded)="onTabAdded($event)" (tabClosed)="onTabClosed($event)" (activeTabChange)="activeTabChange($event)">
405
- <!-- Tab ID 0 is the Home tab (requires homeTab: true in tabConfig) -->
406
- <cats-ui-tab-content [tabId]="0">Home Content</cats-ui-tab-content>
407
- <cats-ui-tab-content [tabId]="1">Tab 1 Content</cats-ui-tab-content>
408
- <cats-ui-tab-content [tabId]="2">Tab 2 Content</cats-ui-tab-content>
409
- </cats-ui-tabset>
410
- ```
411
-
412
- **TypeScript:**
413
-
414
- ```typescript
415
- tabConfig = {
416
- addTab: true, // Show "+" add tab button
417
- closeTab: true, // Show close button on tabs
418
- homeTab: true, // Enable a fixed home tab at ID 0
419
- type: 'Stroke', // Tab style variant
420
- };
421
-
422
- tab1 = [
423
- { id: 1, title: 'Tab1' },
424
- {
425
- id: 2,
426
- title: 'Tab2',
427
- leadingIcon: 'images/command.svg',
428
- tralingIocn: 'images/x-circle.svg',
429
- count: 67,
430
- },
431
- ];
432
-
433
- activeTab: 1;
434
- tab = 6; // counter for dynamic tab IDs
435
-
436
- onTabAdded(ev: any) {
437
- const newTab = {
438
- id: ++this.tab,
439
- title: `Dynamic Tab ${this.tab}`,
440
- };
441
- this.tab1 = [...this.tab1, newTab];
442
- this.activeTab = newTab.id;
443
- }
444
-
445
- onTabClosed(id: number) {
446
- console.log('Tab closed:', id);
447
- }
448
-
449
- activeTabChange(dt: any) {
450
- console.log('Active tab:', dt);
451
- }
452
- ```
453
-
454
- **Tab item options:**
455
-
456
- | Property | Type | Description |
457
- | ------------- | -------- | -------------------------------- |
458
- | `id` | `number` | Unique tab ID |
459
- | `title` | `string` | Tab label |
460
- | `leadingIcon` | `string` | Icon path shown before the title |
461
- | `tralingIocn` | `string` | Icon path shown after the title |
462
- | `count` | `number` | Badge count shown on the tab |
463
-
464
- ---
465
-
466
- ### `WizardComponent` โ€” `<cats-ui-wizard>`
467
-
468
- A multi-step wizard modal with optional progress bar, step badge, and expandable layout. Steps are defined via `ng-template` using the `wizardStep` directive, and wizard state is managed through an injected `WizardService`.
469
-
470
- **Template:**
471
-
472
- ```html
473
- <!-- Trigger button -->
474
- <button (click)="openUserWizard()">Open User Wizard</button>
475
-
476
- @if (wizard.isOpen('classification')()) {
477
- <cats-ui-wizard wizardId="classification" title="Data Classification" [showProgressBar]="true" [showStepBadge]="true" (closed)="closeModal()">
478
- <ng-template wizardStep>
479
- <app-step-one></app-step-one>
480
- </ng-template>
481
-
482
- <ng-template wizardStep>
483
- <app-step-two></app-step-two>
484
- </ng-template>
485
-
486
- <ng-template wizardStep>
487
- <app-step-three></app-step-three>
488
- </ng-template>
489
-
490
- <ng-template wizardStep>
491
- <app-step-four></app-step-four>
492
- </ng-template>
493
- </cats-ui-wizard>
494
- }
495
- ```
496
-
497
- **TypeScript:**
498
-
499
- ```typescript
500
- import { WizardService } from "cats-ui-lib";
501
-
502
- export class ParentComponent {
503
- constructor(public wizard: WizardService) {}
504
-
505
- openUserWizard() {
506
- const wizardId = "classification";
507
-
508
- // Define the step titles and initial states
509
- this.wizard.stepConfig.update((config: any) => {
510
- config[wizardId] = [
511
- { title: "User Info", state: "active" },
512
- { title: "Details", state: "normal" },
513
- { title: "Review", state: "normal" },
514
- { title: "Confirm", state: "normal" },
515
- ];
516
- return config;
517
- });
518
-
519
- this.wizard.open(wizardId, { steps: [] });
520
- }
521
-
522
- closeModal() {
523
- this.wizard.close("classification");
524
- }
525
- }
526
- ```
527
-
528
- **Component inputs:**
529
-
530
- | Input | Type | Description |
531
- | ----------------- | --------- | ----------------------------------------------------- |
532
- | `wizardId` | `string` | Unique identifier matching the ID used in the service |
533
- | `title` | `string` | Title displayed in the wizard header |
534
- | `showProgressBar` | `boolean` | Show a progress bar across the top of the wizard |
535
- | `showStepBadge` | `boolean` | Show a step counter badge (e.g. "Step 2 of 4") |
536
- | `expandable` | `boolean` | Allow the wizard to be expanded to full screen |
537
-
538
- **Component outputs:**
539
-
540
- | Output | Type | Description |
541
- | -------- | -------------------- | --------------------------------- |
542
- | `closed` | `EventEmitter<void>` | Emitted when the wizard is closed |
543
-
544
- **`WizardService` API:**
545
-
546
- | Method / Property | Signature | Description |
547
- | ----------------- | ------------------------------------------------ | ------------------------------------------------- |
548
- | `open()` | `open(id: string, options: { steps: [] }): void` | Opens the wizard with the given ID |
549
- | `close()` | `close(id: string): void` | Closes the wizard with the given ID |
550
- | `isOpen()` | `isOpen(id: string): Signal<boolean>` | Returns a signal indicating if the wizard is open |
551
- | `stepConfig` | `WritableSignal<Record<string, StepConfig[]>>` | Signal holding step definitions per wizard ID |
552
-
553
- **Step config object fields:**
554
-
555
- | Field | Type | Description |
556
- | ------- | -------- | ------------------------------------------------- |
557
- | `title` | `string` | Display label for the step in the progress bar |
558
- | `state` | `string` | Initial state: `'active'` (current) or `'normal'` |
559
-
560
- **Notes:**
561
-
562
- - Each `<ng-template wizardStep>` maps to a step in the order it appears.
563
- - The number of `<ng-template wizardStep>` blocks should match the number of entries in `stepConfig`.
564
- - The wizard uses Angular Signals internally; use `wizard.isOpen('id')()` (note the call `()`) to read the signal value in templates.
565
-
566
- ---
567
-
568
- ### `CustomDatePickerComponent` โ€” `<cats-ui-custom-date-picker>`
569
-
570
- Supports `single`, `range`, and `dual` modes with optional time selection.
571
-
572
- | Mode | Description |
573
- | -------- | ---------------------------------- |
574
- | `single` | Single date picker (ยฑ time) |
575
- | `range` | Start and end date picker (ยฑ time) |
576
- | `dual` | Two-calendar view (ยฑ time) |
577
-
578
- **Template:**
579
-
580
- ```html
581
- <!-- Single date + time -->
582
- <cats-ui-custom-date-picker [config]="{ mode: 'single', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
583
-
584
- <!-- Date range -->
585
- <cats-ui-custom-date-picker [config]="{ mode: 'range', time: false, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
586
-
587
- <!-- Date range + time -->
588
- <cats-ui-custom-date-picker [config]="{ mode: 'range', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
589
-
590
- <!-- Dual calendar -->
591
- <cats-ui-custom-date-picker [config]="{ mode: 'dual', time: false, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
592
-
593
- <!-- Dual calendar + time -->
594
- <cats-ui-custom-date-picker [config]="{ mode: 'dual', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
595
- ```
596
-
597
- **Config options:**
598
-
599
- | Property | Type | Description |
600
- | ------------------ | --------- | --------------------------------------------- |
601
- | `mode` | `string` | `'single'` \| `'range'` \| `'dual'` |
602
- | `time` | `boolean` | Show time picker alongside the date |
603
- | `parentDateFormat` | `string` | Output date format, e.g. `'MM/dd/yyyy'` |
604
- | `minDate` | `Date` | Minimum selectable date |
605
- | `maxDate` | `Date` | Maximum selectable date |
606
- | `placeholder` | `string` | Placeholder for single-date mode |
607
- | `fromPlaceholder` | `string` | Placeholder for start date in range/dual mode |
608
- | `toPlaceholder` | `string` | Placeholder for end date in range/dual mode |
609
- | `disabledDates` | `Date[]` | Array of dates to disable |
610
- | `disablePastDays` | `number` | Number of past days to disable |
611
- | `showDateLabel` | `boolean` | Show label above date input |
612
- | `showTimeLabel` | `boolean` | Show label above time input |
613
-
614
- ---
615
-
616
- ### `TimestampFilterComponent` โ€” `<cats-ui-timestamp-filter>`
617
-
618
- A pre-built filter component with quick date presets, custom input, and date picker submenus.
619
-
620
- **Template:**
621
-
622
- ```html
623
- <cats-ui-timestamp-filter [config]="timeFilterConfig" (selectionChange)="onFilterChange($event)"> </cats-ui-timestamp-filter>
624
- ```
625
-
626
- **TypeScript:**
627
-
628
- ```typescript
629
- timeFilterConfig = {
630
- title: 'Timestamp Filter',
631
- showReset: true,
632
- options: [
633
- { label: 'Live', value: 'live' },
634
- { label: 'Today', value: 'today', default: true },
635
- { label: 'This Week', value: 'week' },
636
- { label: 'This Month', value: 'month' },
637
- { label: 'This Financial Year', value: 'fy' },
638
- { label: 'Last 24 Hours', value: '24h' },
639
- { label: 'Last 30 days', value: '30d' },
640
-
641
- // Custom number input (e.g. "Last N days")
642
- { label: 'Last', value: 'last', type: 'input', custom: true },
643
-
644
- // Date picker submenus
645
- {
646
- label: 'Custom Date',
647
- value: 'date',
648
- type: 'submenu',
649
- custom: true,
650
- pickerMode: 'single',
651
- parentDateFormat: 'MM/dd/yyyy',
652
- },
653
- {
654
- label: 'Custom Date and Time',
655
- value: 'datetime',
656
- type: 'submenu',
657
- custom: true,
658
- pickerMode: 'single',
659
- parentDateFormat: 'MM/dd/yyyy',
660
- },
661
- {
662
- label: 'Custom Date Range',
663
- value: 'range',
664
- type: 'submenu',
665
- custom: true,
666
- pickerMode: 'range',
667
- },
668
- {
669
- label: 'Custom Date and Time Range',
670
- value: 'datetimerange',
671
- type: 'submenu',
672
- custom: true,
673
- },
674
- ],
675
- };
676
-
677
- onFilterChange(dt: any) {
678
- console.log('timestamp filter', dt);
679
- }
680
- ```
681
-
682
- **Config options:**
683
-
684
- | Property | Type | Description |
685
- | ----------- | --------- | ------------------------------ |
686
- | `title` | `string` | Label shown above the filter |
687
- | `showReset` | `boolean` | Show a reset button |
688
- | `options` | `array` | Array of filter option objects |
689
-
690
- **Option object fields:**
691
-
692
- | Field | Type | Description |
693
- | ------------------ | --------- | -------------------------------------------------------------- |
694
- | `label` | `string` | Display label for the option |
695
- | `value` | `string` | Emitted value on selection |
696
- | `default` | `boolean` | Pre-select this option on load |
697
- | `type` | `string` | `'input'` for numeric entry, `'submenu'` for date picker popup |
698
- | `custom` | `boolean` | Marks as a custom/user-defined option |
699
- | `pickerMode` | `string` | Date picker mode: `'single'` \| `'range'` |
700
- | `parentDateFormat` | `string` | Output date format for picker submenus |
701
-
702
- ---
703
-
704
- ### `Tooltip Directive` โ€” `catsUiTooltip`
705
-
706
- Apply as an attribute on any HTML element.
707
-
708
- ```html
709
- <button catsUiTooltip="This is a tooltip">Hover me</button>
710
- ```
711
-
712
- ---
713
-
714
- ## ๐Ÿ“ Project Structure
715
-
716
- ```
717
- cats-ui-lib/
718
- โ”œโ”€โ”€ accordion/
719
- โ”œโ”€โ”€ auto-complete-multi-select/
720
- โ”œโ”€โ”€ auto-complete-single-select/
721
- โ”œโ”€โ”€ checkbox-button/
722
- โ”œโ”€โ”€ custom-date-picker/
723
- โ”œโ”€โ”€ date-time-picker/
724
- โ”œโ”€โ”€ input/
725
- โ”œโ”€โ”€ multi-select/
726
- โ”œโ”€โ”€ radio-button/
727
- โ”œโ”€โ”€ search-box/
728
- โ”œโ”€โ”€ single-select/
729
- โ”œโ”€โ”€ tabs/
730
- โ”œโ”€โ”€ tabset/
731
- โ”œโ”€โ”€ timestamp-filter/
732
- โ”œโ”€โ”€ toogle-button/
733
- โ””โ”€โ”€ wizard/
734
- ```
735
-
736
- ---
737
-
738
- ## ๐Ÿ”— Links
739
-
740
- - **npm:** [https://www.npmjs.com/package/cats-ui-lib](https://www.npmjs.com/package/cats-ui-lib)
741
- - **Angular CLI Docs:** [https://angular.dev/tools/cli](https://angular.dev/tools/cli)
742
-
743
- ---
744
-
745
- ## ๐Ÿ› ๏ธ Development
746
-
747
- ### Build the library
748
-
749
- ```bash
750
- ng build cats-ui
751
- ```
752
-
753
- ### Run unit tests
754
-
755
- ```bash
756
- ng test
757
- ```
758
-
759
- ### Publish to npm
760
-
761
- ```bash
762
- ng build cats-ui
763
- cd dist/cats-ui
764
- npm publish
765
- ```
766
-
767
- ---
768
-
769
- ## ๐Ÿ“‹ Requirements
770
-
771
- | Dependency | Version |
772
- | ---------- | ------- |
773
- | Angular | >= 19.x |
774
- | Node.js | >= 18.x |
775
-
776
- ---
777
-
778
- ## ๐Ÿ“„ License
779
-
780
- MIT ยฉ cats-ui-lib
1
+ # cats-ui-lib
2
+
3
+ A comprehensive Angular UI component library built with Angular 19, providing a rich set of reusable, customizable components for modern web applications.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/cats-ui-lib.svg)](https://www.npmjs.com/package/cats-ui-lib)
6
+ [![Angular](https://img.shields.io/badge/Angular-19-red.svg)](https://angular.dev)
7
+
8
+ ---
9
+
10
+ ## ๐Ÿ“ฆ Installation
11
+
12
+ ```bash
13
+ npm install cats-ui-lib
14
+ ```
15
+
16
+ ---
17
+
18
+ ## โš™๏ธ Setup
19
+
20
+ ### 1. Configure `angular.json`
21
+
22
+ Add the following inside the `build > options` section of your `angular.json`:
23
+
24
+ ```json
25
+ "assets": [
26
+ {
27
+ "glob": "**/*",
28
+ "input": "node_modules/cats-ui-lib/assets"
29
+ }
30
+ ],
31
+ "styles": [
32
+ "node_modules/cats-ui-lib/styles/_index.scss"
33
+ ]
34
+ ```
35
+
36
+ ---
37
+
38
+ ## ๐Ÿงฉ Components
39
+
40
+ ---
41
+
42
+ ### `InputComponent` โ€” `<cats-ui-input>`
43
+
44
+ Supports types: `text` ยท `number` ยท `email` ยท `password`
45
+
46
+ **Template:**
47
+
48
+ ```html
49
+ <cats-ui-input [inputConfig]="inputConfig" [(ngModel)]="name" required> </cats-ui-input>
50
+
51
+ <!-- Disabled state -->
52
+ <cats-ui-input [disabled]="true" [inputConfig]="inputConfig" [(ngModel)]="name"> </cats-ui-input>
53
+ ```
54
+
55
+ **TypeScript:**
56
+
57
+ ```typescript
58
+ import { InputConfig } from "cats-ui-lib";
59
+
60
+ inputConfig: InputConfig = {
61
+ type: "text",
62
+ placeholder: "Enter value",
63
+ };
64
+ ```
65
+
66
+ **`InputConfig` options:**
67
+
68
+ | Property | Type | Description |
69
+ | ------------- | -------- | ------------------------------------------------- |
70
+ | `type` | `string` | Input type: `text`, `email`, `password`, `number` |
71
+ | `placeholder` | `string` | Placeholder text |
72
+
73
+ ---
74
+
75
+ ### `SingleSelectComponent` โ€” `<cats-ui-single-select>`
76
+
77
+ **Template:**
78
+
79
+ ```html
80
+ <cats-ui-single-select [optionList]="options" [singleSelectConfig]="singleConfig" [parentNativeElement]="'parent'" (onSelection)="onSelection($event)"> </cats-ui-single-select>
81
+ ```
82
+
83
+ **TypeScript:**
84
+
85
+ ```typescript
86
+ import { SingleSelectConfig } from 'cats-ui-lib';
87
+
88
+ options = [
89
+ { id: 1, name: 'Option 1', disable: false },
90
+ { id: 2, name: 'Option 2', disable: false },
91
+ ];
92
+
93
+ singleConfig: SingleSelectConfig = {
94
+ idField: 'id',
95
+ textField: 'name',
96
+ disabledField: 'disable',
97
+ placeholder: 'Select Option',
98
+ };
99
+
100
+ onSelection(dt: any) {
101
+ console.log('Selected:', dt);
102
+ }
103
+ ```
104
+
105
+ **`SingleSelectConfig` options:**
106
+
107
+ | Property | Type | Description |
108
+ | --------------- | -------- | ------------------------------ |
109
+ | `idField` | `string` | Key for option ID |
110
+ | `textField` | `string` | Key for display label |
111
+ | `disabledField` | `string` | Key to mark option as disabled |
112
+ | `placeholder` | `string` | Placeholder text |
113
+
114
+ ---
115
+
116
+ ### `MultiSelectComponent` โ€” `<cats-ui-multi-select>`
117
+
118
+ **Template:**
119
+
120
+ ```html
121
+ <cats-ui-multi-select [optionList]="options" [multiSelectConfig]="multiSelectConfig" (onSelection)="onSelection($event)"> </cats-ui-multi-select>
122
+ ```
123
+
124
+ **TypeScript:**
125
+
126
+ ```typescript
127
+ import { MultiSelectConfig } from "cats-ui-lib";
128
+
129
+ multiSelectConfig: MultiSelectConfig = {
130
+ idField: "id",
131
+ textField: "name",
132
+ disabledField: "disable",
133
+ placeholder: "Select Option",
134
+ prefixLabel: "",
135
+ enableSearch: true,
136
+ chipLimit: 2,
137
+ selectAll: true,
138
+ required: false,
139
+ };
140
+ ```
141
+
142
+ **`MultiSelectConfig` options:**
143
+
144
+ | Property | Type | Description |
145
+ | --------------- | --------- | ---------------------------------------- |
146
+ | `idField` | `string` | Key for option ID |
147
+ | `textField` | `string` | Key for display label |
148
+ | `disabledField` | `string` | Key to mark option as disabled |
149
+ | `placeholder` | `string` | Placeholder text |
150
+ | `prefixLabel` | `string` | Label prefix shown before selected chips |
151
+ | `enableSearch` | `boolean` | Show search input inside dropdown |
152
+ | `chipLimit` | `number` | Max chips to display before `+N more` |
153
+ | `selectAll` | `boolean` | Show "Select All" option |
154
+ | `required` | `boolean` | Mark field as required |
155
+
156
+ ---
157
+
158
+ ### `AutoComplete SingleSelect` โ€” `<cats-ui-input-single-select>`
159
+
160
+ **Template:**
161
+
162
+ ```html
163
+ <cats-ui-input-single-select [optionsList]="options" [autoSingleSelectConfig]="autoSingleSelectConfig" (onItemSelection)="onSelection($event)"> </cats-ui-input-single-select>
164
+ ```
165
+
166
+ **TypeScript:**
167
+
168
+ ```typescript
169
+ import { AutoCompleteSingleSelectConfig } from "cats-ui-lib";
170
+
171
+ autoSingleSelectConfig: AutoCompleteSingleSelectConfig = {
172
+ idField: "id",
173
+ textField: "name",
174
+ disabledField: "",
175
+ placeholder: "Enter or select",
176
+ required: false,
177
+ customInput: true,
178
+ };
179
+ ```
180
+
181
+ **`AutoCompleteSingleSelectConfig` options:**
182
+
183
+ | Property | Type | Description |
184
+ | --------------- | --------- | ---------------------------------------- |
185
+ | `idField` | `string` | Key for option ID |
186
+ | `textField` | `string` | Key for display label |
187
+ | `disabledField` | `string` | Key to mark option as disabled |
188
+ | `placeholder` | `string` | Placeholder text |
189
+ | `required` | `boolean` | Mark field as required |
190
+ | `customInput` | `boolean` | Allow free-text input not in option list |
191
+
192
+ ---
193
+
194
+ ### `AutoComplete MultiSelect` โ€” `<cats-ui-input-multi-select>`
195
+
196
+ **Template:**
197
+
198
+ ```html
199
+ <cats-ui-input-multi-select [optionsList]="options" [autoCompleteMultiSelectConfig]="autoMultiSelectConfig" (onItemSelection)="onSelection($event)"> </cats-ui-input-multi-select>
200
+ ```
201
+
202
+ **TypeScript:**
203
+
204
+ ```typescript
205
+ import { AutoCompleteMultiSelectConfig } from "cats-ui-lib";
206
+
207
+ autoMultiSelectConfig: AutoCompleteMultiSelectConfig = {
208
+ idField: "id",
209
+ textField: "name",
210
+ disabledField: "disable",
211
+ placeholder: "Type to Search",
212
+ selectAll: false,
213
+ chipLimit: 2,
214
+ customInput: false,
215
+ infoText: "Select any 8 KPIs",
216
+ selectionLimit: 5,
217
+ };
218
+ ```
219
+
220
+ **`AutoCompleteMultiSelectConfig` options:**
221
+
222
+ | Property | Type | Description |
223
+ | ---------------- | --------- | ---------------------------------------- |
224
+ | `idField` | `string` | Key for option ID |
225
+ | `textField` | `string` | Key for display label |
226
+ | `disabledField` | `string` | Key to mark option as disabled |
227
+ | `placeholder` | `string` | Placeholder text (supports HTML) |
228
+ | `selectAll` | `boolean` | Show "Select All" option |
229
+ | `chipLimit` | `number` | Max chips shown before `+N more` |
230
+ | `customInput` | `boolean` | Allow free-text input |
231
+ | `infoText` | `string` | Helper text shown below the input |
232
+ | `selectionLimit` | `number` | Max number of items that can be selected |
233
+
234
+ ---
235
+
236
+ ### `SearchBoxComponent` โ€” `<cats-ui-search-box>`
237
+
238
+ **Template:**
239
+
240
+ ```html
241
+ <cats-ui-search-box [searchConfig]="searchConfig" (searchParamValue)="searchParamValue($event)"> </cats-ui-search-box>
242
+ ```
243
+
244
+ **TypeScript:**
245
+
246
+ ```typescript
247
+ import { SearchConfig } from 'cats-ui-lib';
248
+
249
+ searchConfig: SearchConfig = {
250
+ serachValue: '',
251
+ placeholder: 'Search Here',
252
+ };
253
+
254
+ searchParamValue(data: any) {
255
+ console.log('searchParamValue', data);
256
+ }
257
+ ```
258
+
259
+ ---
260
+
261
+ ### `AccordionComponent` โ€” `<cats-ui-accordion>`
262
+
263
+ **Template:**
264
+
265
+ ```html
266
+ <cats-ui-accordion>
267
+ <cats-ui-accordion-item title="Panel 1" [index]="0">
268
+ <ng-template>
269
+ <p>Content for Panel 1.</p>
270
+ </ng-template>
271
+ </cats-ui-accordion-item>
272
+
273
+ <cats-ui-accordion-item title="Panel 2" [index]="1">
274
+ <ng-template>
275
+ <p>Content for Panel 2.</p>
276
+ </ng-template>
277
+ </cats-ui-accordion-item>
278
+ </cats-ui-accordion>
279
+ ```
280
+
281
+ ---
282
+
283
+ ### `RadioButtonComponent` โ€” `<cats-ui-radio-button>`
284
+
285
+ **Template:**
286
+
287
+ ```html
288
+ <cats-ui-radio-button [config]="radioConfig" [optionList]="options" (selectionChange)="onRadio($event)"> </cats-ui-radio-button>
289
+ ```
290
+
291
+ **TypeScript:**
292
+
293
+ ```typescript
294
+ import { RadioButtonConfig } from 'cats-ui-lib';
295
+
296
+ radioConfig: RadioButtonConfig = {
297
+ valueField: 'id',
298
+ textField: 'name',
299
+ name: 'gender',
300
+ disabled: 'disable',
301
+ };
302
+
303
+ options = [
304
+ { id: 1, name: 'Option 1', disable: false },
305
+ { id: 2, name: 'Option 2', disable: false },
306
+ ];
307
+
308
+ onRadio(data: any) {
309
+ console.log('radio', data);
310
+ }
311
+ ```
312
+
313
+ **`RadioButtonConfig` options:**
314
+
315
+ | Property | Type | Description |
316
+ | ------------ | -------- | --------------------------------- |
317
+ | `valueField` | `string` | Key for option value |
318
+ | `textField` | `string` | Key for display label |
319
+ | `name` | `string` | HTML radio group name |
320
+ | `disabled` | `string` | Key to mark an option as disabled |
321
+
322
+ ---
323
+
324
+ ### `CheckboxComponent` โ€” `<cats-ui-checkbox-button>`
325
+
326
+ **Template:**
327
+
328
+ ```html
329
+ <cats-ui-checkbox-button [checkBoxConfig]="checkBoxConfig" [optionList]="taskOptions" (onCheckBoxSelection)="checkBox($event)"> </cats-ui-checkbox-button>
330
+ ```
331
+
332
+ **TypeScript:**
333
+
334
+ ```typescript
335
+ import { CheckBoxConfig } from 'cats-ui-lib';
336
+
337
+ checkBoxConfig: CheckBoxConfig = {
338
+ idField: 'id',
339
+ textField: 'name',
340
+ name: 'check23',
341
+ disabledField: 'disable',
342
+ };
343
+
344
+ taskOptions = [
345
+ { id: '101', name: 'Parent Task 1', disable: true },
346
+ { id: '102', name: 'Parent Task 2', disable: false },
347
+ ];
348
+
349
+ checkBox(data: any) {
350
+ console.log('checkbox selection', data);
351
+ }
352
+ ```
353
+
354
+ **`CheckBoxConfig` options:**
355
+
356
+ | Property | Type | Description |
357
+ | --------------- | -------- | --------------------------------- |
358
+ | `idField` | `string` | Key for option ID |
359
+ | `textField` | `string` | Key for display label |
360
+ | `name` | `string` | HTML checkbox group name |
361
+ | `disabledField` | `string` | Key to mark an option as disabled |
362
+
363
+ ---
364
+
365
+ ### `ToggleComponent` โ€” `<cats-ui-toogle-button>`
366
+
367
+ **Template:**
368
+
369
+ ```html
370
+ <cats-ui-toogle-button [toggleConfig]="toggleConfig" (onToggled)="onToggled($event)"> </cats-ui-toogle-button>
371
+ ```
372
+
373
+ **TypeScript:**
374
+
375
+ ```typescript
376
+ import { ToggleConfig } from 'cats-ui-lib';
377
+
378
+ toggleConfig: ToggleConfig = {
379
+ disabled: false,
380
+ checked: false,
381
+ };
382
+
383
+ onToggled(data: any) {
384
+ console.log('toggled', data);
385
+ }
386
+ ```
387
+
388
+ **`ToggleConfig` options:**
389
+
390
+ | Property | Type | Description |
391
+ | ---------- | --------- | --------------------- |
392
+ | `disabled` | `boolean` | Disable the toggle |
393
+ | `checked` | `boolean` | Initial checked state |
394
+
395
+ ---
396
+
397
+ ### `TabsetComponent` โ€” `<cats-ui-tabset>`
398
+
399
+ An advanced tabset with add/close tab support, icons, badge counts, and a home tab.
400
+
401
+ **Template:**
402
+
403
+ ```html
404
+ <cats-ui-tabset [tabs]="tab1" [activeTab]="activeTab" [tabConfig]="tabConfig" (tabAdded)="onTabAdded($event)" (tabClosed)="onTabClosed($event)" (activeTabChange)="activeTabChange($event)">
405
+ <!-- Tab ID 0 is the Home tab (requires homeTab: true in tabConfig) -->
406
+ <cats-ui-tab-content [tabId]="0">Home Content</cats-ui-tab-content>
407
+ <cats-ui-tab-content [tabId]="1">Tab 1 Content</cats-ui-tab-content>
408
+ <cats-ui-tab-content [tabId]="2">Tab 2 Content</cats-ui-tab-content>
409
+ </cats-ui-tabset>
410
+ ```
411
+
412
+ **TypeScript:**
413
+
414
+ ```typescript
415
+ tabConfig = {
416
+ addTab: true, // Show "+" add tab button
417
+ closeTab: true, // Show close button on tabs
418
+ homeTab: true, // Enable a fixed home tab at ID 0
419
+ type: 'Stroke', // Tab style variant
420
+ };
421
+
422
+ tab1 = [
423
+ { id: 1, title: 'Tab1' },
424
+ {
425
+ id: 2,
426
+ title: 'Tab2',
427
+ leadingIcon: 'images/command.svg',
428
+ tralingIocn: 'images/x-circle.svg',
429
+ count: 67,
430
+ },
431
+ ];
432
+
433
+ activeTab: 1;
434
+ tab = 6; // counter for dynamic tab IDs
435
+
436
+ onTabAdded(ev: any) {
437
+ const newTab = {
438
+ id: ++this.tab,
439
+ title: `Dynamic Tab ${this.tab}`,
440
+ };
441
+ this.tab1 = [...this.tab1, newTab];
442
+ this.activeTab = newTab.id;
443
+ }
444
+
445
+ onTabClosed(id: number) {
446
+ console.log('Tab closed:', id);
447
+ }
448
+
449
+ activeTabChange(dt: any) {
450
+ console.log('Active tab:', dt);
451
+ }
452
+ ```
453
+
454
+ **Tab item options:**
455
+
456
+ | Property | Type | Description |
457
+ | ------------- | -------- | -------------------------------- |
458
+ | `id` | `number` | Unique tab ID |
459
+ | `title` | `string` | Tab label |
460
+ | `leadingIcon` | `string` | Icon path shown before the title |
461
+ | `tralingIocn` | `string` | Icon path shown after the title |
462
+ | `count` | `number` | Badge count shown on the tab |
463
+
464
+ ---
465
+
466
+ ### `WizardComponent` โ€” `<cats-ui-wizard>`
467
+
468
+ A multi-step wizard modal with optional progress bar, step badge, and expandable layout. Steps are defined via `ng-template` using the `wizardStep` directive, and wizard state is managed through an injected `WizardService`.
469
+
470
+ **Template:**
471
+
472
+ ```html
473
+ <!-- Trigger button -->
474
+ <button (click)="openUserWizard()">Open User Wizard</button>
475
+
476
+ @if (wizard.isOpen('classification')()) {
477
+ <cats-ui-wizard wizardId="classification" title="Data Classification" [showProgressBar]="true" [showStepBadge]="true" (closed)="closeModal()">
478
+ <ng-template wizardStep>
479
+ <app-step-one></app-step-one>
480
+ </ng-template>
481
+
482
+ <ng-template wizardStep>
483
+ <app-step-two></app-step-two>
484
+ </ng-template>
485
+
486
+ <ng-template wizardStep>
487
+ <app-step-three></app-step-three>
488
+ </ng-template>
489
+
490
+ <ng-template wizardStep>
491
+ <app-step-four></app-step-four>
492
+ </ng-template>
493
+ </cats-ui-wizard>
494
+ }
495
+ ```
496
+
497
+ **TypeScript:**
498
+
499
+ ```typescript
500
+ import { WizardService } from "cats-ui-lib";
501
+
502
+ export class ParentComponent {
503
+ constructor(public wizard: WizardService) {}
504
+
505
+ openUserWizard() {
506
+ const wizardId = "classification";
507
+
508
+ // Define the step titles and initial states
509
+ this.wizard.stepConfig.update((config: any) => {
510
+ config[wizardId] = [
511
+ { title: "User Info", state: "active" },
512
+ { title: "Details", state: "normal" },
513
+ { title: "Review", state: "normal" },
514
+ { title: "Confirm", state: "normal" },
515
+ ];
516
+ return config;
517
+ });
518
+
519
+ this.wizard.open(wizardId, { steps: [] });
520
+ }
521
+
522
+ closeModal() {
523
+ this.wizard.close("classification");
524
+ }
525
+ }
526
+ ```
527
+
528
+ **Component inputs:**
529
+
530
+ | Input | Type | Description |
531
+ | ----------------- | --------- | ----------------------------------------------------- |
532
+ | `wizardId` | `string` | Unique identifier matching the ID used in the service |
533
+ | `title` | `string` | Title displayed in the wizard header |
534
+ | `showProgressBar` | `boolean` | Show a progress bar across the top of the wizard |
535
+ | `showStepBadge` | `boolean` | Show a step counter badge (e.g. "Step 2 of 4") |
536
+ | `expandable` | `boolean` | Allow the wizard to be expanded to full screen |
537
+
538
+ **Component outputs:**
539
+
540
+ | Output | Type | Description |
541
+ | -------- | -------------------- | --------------------------------- |
542
+ | `closed` | `EventEmitter<void>` | Emitted when the wizard is closed |
543
+
544
+ **`WizardService` API:**
545
+
546
+ | Method / Property | Signature | Description |
547
+ | ----------------- | ------------------------------------------------ | ------------------------------------------------- |
548
+ | `open()` | `open(id: string, options: { steps: [] }): void` | Opens the wizard with the given ID |
549
+ | `close()` | `close(id: string): void` | Closes the wizard with the given ID |
550
+ | `isOpen()` | `isOpen(id: string): Signal<boolean>` | Returns a signal indicating if the wizard is open |
551
+ | `stepConfig` | `WritableSignal<Record<string, StepConfig[]>>` | Signal holding step definitions per wizard ID |
552
+
553
+ **Step config object fields:**
554
+
555
+ | Field | Type | Description |
556
+ | ------- | -------- | ------------------------------------------------- |
557
+ | `title` | `string` | Display label for the step in the progress bar |
558
+ | `state` | `string` | Initial state: `'active'` (current) or `'normal'` |
559
+
560
+ **Notes:**
561
+
562
+ - Each `<ng-template wizardStep>` maps to a step in the order it appears.
563
+ - The number of `<ng-template wizardStep>` blocks should match the number of entries in `stepConfig`.
564
+ - The wizard uses Angular Signals internally; use `wizard.isOpen('id')()` (note the call `()`) to read the signal value in templates.
565
+
566
+ ---
567
+
568
+ ### `CustomDatePickerComponent` โ€” `<cats-ui-custom-date-picker>`
569
+
570
+ Supports `single`, `range`, and `dual` modes with optional time selection.
571
+
572
+ | Mode | Description |
573
+ | -------- | ---------------------------------- |
574
+ | `single` | Single date picker (ยฑ time) |
575
+ | `range` | Start and end date picker (ยฑ time) |
576
+ | `dual` | Two-calendar view (ยฑ time) |
577
+
578
+ **Template:**
579
+
580
+ ```html
581
+ <!-- Single date + time -->
582
+ <cats-ui-custom-date-picker [config]="{ mode: 'single', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
583
+
584
+ <!-- Date range -->
585
+ <cats-ui-custom-date-picker [config]="{ mode: 'range', time: false, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
586
+
587
+ <!-- Date range + time -->
588
+ <cats-ui-custom-date-picker [config]="{ mode: 'range', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
589
+
590
+ <!-- Dual calendar -->
591
+ <cats-ui-custom-date-picker [config]="{ mode: 'dual', time: false, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
592
+
593
+ <!-- Dual calendar + time -->
594
+ <cats-ui-custom-date-picker [config]="{ mode: 'dual', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
595
+ ```
596
+
597
+ **Config options:**
598
+
599
+ | Property | Type | Description |
600
+ | ------------------ | --------- | --------------------------------------------- |
601
+ | `mode` | `string` | `'single'` \| `'range'` \| `'dual'` |
602
+ | `time` | `boolean` | Show time picker alongside the date |
603
+ | `parentDateFormat` | `string` | Output date format, e.g. `'MM/dd/yyyy'` |
604
+ | `minDate` | `Date` | Minimum selectable date |
605
+ | `maxDate` | `Date` | Maximum selectable date |
606
+ | `placeholder` | `string` | Placeholder for single-date mode |
607
+ | `fromPlaceholder` | `string` | Placeholder for start date in range/dual mode |
608
+ | `toPlaceholder` | `string` | Placeholder for end date in range/dual mode |
609
+ | `disabledDates` | `Date[]` | Array of dates to disable |
610
+ | `disablePastDays` | `number` | Number of past days to disable |
611
+ | `showDateLabel` | `boolean` | Show label above date input |
612
+ | `showTimeLabel` | `boolean` | Show label above time input |
613
+
614
+ ---
615
+
616
+ ### `TimestampFilterComponent` โ€” `<cats-ui-timestamp-filter>`
617
+
618
+ A pre-built filter component with quick date presets, custom input, and date picker submenus.
619
+
620
+ **Template:**
621
+
622
+ ```html
623
+ <cats-ui-timestamp-filter [config]="timeFilterConfig" (selectionChange)="onFilterChange($event)"> </cats-ui-timestamp-filter>
624
+ ```
625
+
626
+ **TypeScript:**
627
+
628
+ ```typescript
629
+ timeFilterConfig = {
630
+ title: 'Timestamp Filter',
631
+ showReset: true,
632
+ options: [
633
+ { label: 'Live', value: 'live' },
634
+ { label: 'Today', value: 'today', default: true },
635
+ { label: 'This Week', value: 'week' },
636
+ { label: 'This Month', value: 'month' },
637
+ { label: 'This Financial Year', value: 'fy' },
638
+ { label: 'Last 24 Hours', value: '24h' },
639
+ { label: 'Last 30 days', value: '30d' },
640
+
641
+ // Custom number input (e.g. "Last N days")
642
+ { label: 'Last', value: 'last', type: 'input', custom: true },
643
+
644
+ // Date picker submenus
645
+ {
646
+ label: 'Custom Date',
647
+ value: 'date',
648
+ type: 'submenu',
649
+ custom: true,
650
+ pickerMode: 'single',
651
+ parentDateFormat: 'MM/dd/yyyy',
652
+ },
653
+ {
654
+ label: 'Custom Date and Time',
655
+ value: 'datetime',
656
+ type: 'submenu',
657
+ custom: true,
658
+ pickerMode: 'single',
659
+ parentDateFormat: 'MM/dd/yyyy',
660
+ },
661
+ {
662
+ label: 'Custom Date Range',
663
+ value: 'range',
664
+ type: 'submenu',
665
+ custom: true,
666
+ pickerMode: 'range',
667
+ },
668
+ {
669
+ label: 'Custom Date and Time Range',
670
+ value: 'datetimerange',
671
+ type: 'submenu',
672
+ custom: true,
673
+ },
674
+ ],
675
+ };
676
+
677
+ onFilterChange(dt: any) {
678
+ console.log('timestamp filter', dt);
679
+ }
680
+ ```
681
+
682
+ **Config options:**
683
+
684
+ | Property | Type | Description |
685
+ | ----------- | --------- | ------------------------------ |
686
+ | `title` | `string` | Label shown above the filter |
687
+ | `showReset` | `boolean` | Show a reset button |
688
+ | `options` | `array` | Array of filter option objects |
689
+
690
+ **Option object fields:**
691
+
692
+ | Field | Type | Description |
693
+ | ------------------ | --------- | -------------------------------------------------------------- |
694
+ | `label` | `string` | Display label for the option |
695
+ | `value` | `string` | Emitted value on selection |
696
+ | `default` | `boolean` | Pre-select this option on load |
697
+ | `type` | `string` | `'input'` for numeric entry, `'submenu'` for date picker popup |
698
+ | `custom` | `boolean` | Marks as a custom/user-defined option |
699
+ | `pickerMode` | `string` | Date picker mode: `'single'` \| `'range'` |
700
+ | `parentDateFormat` | `string` | Output date format for picker submenus |
701
+
702
+ ---
703
+
704
+ ### `Tooltip Directive` โ€” `catsUiTooltip`
705
+
706
+ Apply as an attribute on any HTML element.
707
+
708
+ ```html
709
+ <button catsUiTooltip="This is a tooltip">Hover me</button>
710
+ ```
711
+
712
+ ---
713
+
714
+ ## ๐Ÿ“ Project Structure
715
+
716
+ ```
717
+ cats-ui-lib/
718
+ โ”œโ”€โ”€ accordion/
719
+ โ”œโ”€โ”€ auto-complete-multi-select/
720
+ โ”œโ”€โ”€ auto-complete-single-select/
721
+ โ”œโ”€โ”€ checkbox-button/
722
+ โ”œโ”€โ”€ custom-date-picker/
723
+ โ”œโ”€โ”€ date-time-picker/
724
+ โ”œโ”€โ”€ input/
725
+ โ”œโ”€โ”€ multi-select/
726
+ โ”œโ”€โ”€ radio-button/
727
+ โ”œโ”€โ”€ search-box/
728
+ โ”œโ”€โ”€ single-select/
729
+ โ”œโ”€โ”€ tabs/
730
+ โ”œโ”€โ”€ tabset/
731
+ โ”œโ”€โ”€ timestamp-filter/
732
+ โ”œโ”€โ”€ toogle-button/
733
+ โ””โ”€โ”€ wizard/
734
+ ```
735
+
736
+ ---
737
+
738
+ ## ๐Ÿ”— Links
739
+
740
+ - **npm:** [https://www.npmjs.com/package/cats-ui-lib](https://www.npmjs.com/package/cats-ui-lib)
741
+ - **Angular CLI Docs:** [https://angular.dev/tools/cli](https://angular.dev/tools/cli)
742
+
743
+ ---
744
+
745
+ ## ๐Ÿ› ๏ธ Development
746
+
747
+ ### Build the library
748
+
749
+ ```bash
750
+ ng build cats-ui
751
+ ```
752
+
753
+ ### Run unit tests
754
+
755
+ ```bash
756
+ ng test
757
+ ```
758
+
759
+ ### Publish to npm
760
+
761
+ ```bash
762
+ ng build cats-ui
763
+ cd dist/cats-ui
764
+ npm publish
765
+ ```
766
+
767
+ ---
768
+
769
+ ## ๐Ÿ“‹ Requirements
770
+
771
+ | Dependency | Version |
772
+ | ---------- | ------- |
773
+ | Angular | >= 19.x |
774
+ | Node.js | >= 18.x |
775
+
776
+ ---
777
+
778
+ ## ๐Ÿ“„ License
779
+
780
+ MIT ยฉ cats-ui-lib