cats-ui-lib 2.0.4 โ†’ 2.0.6

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