cats-ui-lib
v2.2.8
Published
A comprehensive Angular UI component library built with Angular 19, providing a rich set of reusable, customizable components for modern web applications.
Readme
cats-ui-lib
A comprehensive Angular UI component library built with Angular 19, providing a rich set of reusable, customizable components for modern web applications.
📦 Installation
npm install cats-ui-lib⚙️ Setup
1. Configure angular.json
Add the following inside the build > options section of your angular.json:
"assets": [
{
"glob": "**/*",
"input": "node_modules/cats-ui-lib/assets"
}
],
"styles": [
"node_modules/cats-ui-lib/styles/_index.scss"
]🧩 Components
InputComponent — <cats-ui-input>
Supports types: text · number · email · password
Template:
<cats-ui-input [inputConfig]="inputConfig" [(ngModel)]="name" required> </cats-ui-input>
<!-- Disabled state -->
<cats-ui-input [disabled]="true" [inputConfig]="inputConfig" [(ngModel)]="name"> </cats-ui-input>TypeScript:
import { InputConfig } from "cats-ui-lib";
inputConfig: InputConfig = {
type: "text",
placeholder: "Enter value",
};InputConfig options:
| Property | Type | Description |
| ------------- | -------- | ------------------------------------------------- |
| type | string | Input type: text, email, password, number |
| placeholder | string | Placeholder text |
SingleSelectComponent — <cats-ui-single-select>
Template:
<cats-ui-single-select [optionList]="options" [singleSelectConfig]="singleConfig" [parentNativeElement]="'parent'" (onSelection)="onSelection($event)"> </cats-ui-single-select>TypeScript:
import { SingleSelectConfig } from 'cats-ui-lib';
options = [
{ id: 1, name: 'Option 1', disable: false },
{ id: 2, name: 'Option 2', disable: false },
];
singleConfig: SingleSelectConfig = {
idField: 'id',
textField: 'name',
disabledField: 'disable',
placeholder: 'Select Option',
};
onSelection(dt: any) {
console.log('Selected:', dt);
}SingleSelectConfig options:
| Property | Type | Description |
| --------------- | -------- | ------------------------------ |
| idField | string | Key for option ID |
| textField | string | Key for display label |
| disabledField | string | Key to mark option as disabled |
| placeholder | string | Placeholder text |
MultiSelectComponent — <cats-ui-multi-select>
Template:
<cats-ui-multi-select [optionList]="options" [multiSelectConfig]="multiSelectConfig" (onSelection)="onSelection($event)"> </cats-ui-multi-select>TypeScript:
import { MultiSelectConfig } from "cats-ui-lib";
multiSelectConfig: MultiSelectConfig = {
idField: "id",
textField: "name",
disabledField: "disable",
placeholder: "Select Option",
prefixLabel: "",
enableSearch: true,
chipLimit: 2,
selectAll: true,
required: false,
};MultiSelectConfig options:
| Property | Type | Description |
| --------------- | --------- | ---------------------------------------- |
| idField | string | Key for option ID |
| textField | string | Key for display label |
| disabledField | string | Key to mark option as disabled |
| placeholder | string | Placeholder text |
| prefixLabel | string | Label prefix shown before selected chips |
| enableSearch | boolean | Show search input inside dropdown |
| chipLimit | number | Max chips to display before +N more |
| selectAll | boolean | Show "Select All" option |
| required | boolean | Mark field as required |
AutoComplete SingleSelect — <cats-ui-input-single-select>
Template:
<cats-ui-input-single-select [optionsList]="options" [autoSingleSelectConfig]="autoSingleSelectConfig" (onItemSelection)="onSelection($event)"> </cats-ui-input-single-select>TypeScript:
import { AutoCompleteSingleSelectConfig } from "cats-ui-lib";
autoSingleSelectConfig: AutoCompleteSingleSelectConfig = {
idField: "id",
textField: "name",
disabledField: "",
placeholder: "Enter or select",
required: false,
customInput: true,
};AutoCompleteSingleSelectConfig options:
| Property | Type | Description |
| --------------- | --------- | ---------------------------------------- |
| idField | string | Key for option ID |
| textField | string | Key for display label |
| disabledField | string | Key to mark option as disabled |
| placeholder | string | Placeholder text |
| required | boolean | Mark field as required |
| customInput | boolean | Allow free-text input not in option list |
AutoComplete MultiSelect — <cats-ui-input-multi-select>
Template:
<cats-ui-input-multi-select [optionsList]="options" [autoCompleteMultiSelectConfig]="autoMultiSelectConfig" (onItemSelection)="onSelection($event)"> </cats-ui-input-multi-select>TypeScript:
import { AutoCompleteMultiSelectConfig } from "cats-ui-lib";
autoMultiSelectConfig: AutoCompleteMultiSelectConfig = {
idField: "id",
textField: "name",
disabledField: "disable",
placeholder: "Type to Search",
selectAll: false,
chipLimit: 2,
customInput: false,
infoText: "Select any 8 KPIs",
selectionLimit: 5,
};AutoCompleteMultiSelectConfig options:
| Property | Type | Description |
| ---------------- | --------- | ---------------------------------------- |
| idField | string | Key for option ID |
| textField | string | Key for display label |
| disabledField | string | Key to mark option as disabled |
| placeholder | string | Placeholder text (supports HTML) |
| selectAll | boolean | Show "Select All" option |
| chipLimit | number | Max chips shown before +N more |
| customInput | boolean | Allow free-text input |
| infoText | string | Helper text shown below the input |
| selectionLimit | number | Max number of items that can be selected |
SearchBoxComponent — <cats-ui-search-box>
Template:
<cats-ui-search-box [searchConfig]="searchConfig" (searchParamValue)="searchParamValue($event)"> </cats-ui-search-box>TypeScript:
import { SearchConfig } from 'cats-ui-lib';
searchConfig: SearchConfig = {
serachValue: '',
placeholder: 'Search Here',
};
searchParamValue(data: any) {
console.log('searchParamValue', data);
}AccordionComponent — <cats-ui-accordion>
Template:
<cats-ui-accordion>
<cats-ui-accordion-item title="Panel 1" [index]="0">
<ng-template>
<p>Content for Panel 1.</p>
</ng-template>
</cats-ui-accordion-item>
<cats-ui-accordion-item title="Panel 2" [index]="1">
<ng-template>
<p>Content for Panel 2.</p>
</ng-template>
</cats-ui-accordion-item>
</cats-ui-accordion>RadioButtonComponent — <cats-ui-radio-button>
Template:
<cats-ui-radio-button [config]="radioConfig" [optionList]="options" (selectionChange)="onRadio($event)"> </cats-ui-radio-button>TypeScript:
import { RadioButtonConfig } from 'cats-ui-lib';
radioConfig: RadioButtonConfig = {
valueField: 'id',
textField: 'name',
name: 'gender',
disabled: 'disable',
};
options = [
{ id: 1, name: 'Option 1', disable: false },
{ id: 2, name: 'Option 2', disable: false },
];
onRadio(data: any) {
console.log('radio', data);
}RadioButtonConfig options:
| Property | Type | Description |
| ------------ | -------- | --------------------------------- |
| valueField | string | Key for option value |
| textField | string | Key for display label |
| name | string | HTML radio group name |
| disabled | string | Key to mark an option as disabled |
CheckboxComponent — <cats-ui-checkbox-button>
Template:
<cats-ui-checkbox-button [checkBoxConfig]="checkBoxConfig" [optionList]="taskOptions" (onCheckBoxSelection)="checkBox($event)"> </cats-ui-checkbox-button>TypeScript:
import { CheckBoxConfig } from 'cats-ui-lib';
checkBoxConfig: CheckBoxConfig = {
idField: 'id',
textField: 'name',
name: 'check23',
disabledField: 'disable',
};
taskOptions = [
{ id: '101', name: 'Parent Task 1', disable: true },
{ id: '102', name: 'Parent Task 2', disable: false },
];
checkBox(data: any) {
console.log('checkbox selection', data);
}CheckBoxConfig options:
| Property | Type | Description |
| --------------- | -------- | --------------------------------- |
| idField | string | Key for option ID |
| textField | string | Key for display label |
| name | string | HTML checkbox group name |
| disabledField | string | Key to mark an option as disabled |
ToggleComponent — <cats-ui-toogle-button>
Template:
<cats-ui-toogle-button [toggleConfig]="toggleConfig" (onToggled)="onToggled($event)"> </cats-ui-toogle-button>TypeScript:
import { ToggleConfig } from 'cats-ui-lib';
toggleConfig: ToggleConfig = {
disabled: false,
checked: false,
};
onToggled(data: any) {
console.log('toggled', data);
}ToggleConfig options:
| Property | Type | Description |
| ---------- | --------- | --------------------- |
| disabled | boolean | Disable the toggle |
| checked | boolean | Initial checked state |
TabsetComponent — <cats-ui-tabset>
An advanced tabset with add/close tab support, icons, badge counts, and a home tab.
Template:
<cats-ui-tabset [tabs]="tab1" [activeTab]="activeTab" [tabConfig]="tabConfig" (tabAdded)="onTabAdded($event)" (tabClosed)="onTabClosed($event)" (activeTabChange)="activeTabChange($event)">
<!-- Tab ID 0 is the Home tab (requires homeTab: true in tabConfig) -->
<cats-ui-tab-content [tabId]="0">Home Content</cats-ui-tab-content>
<cats-ui-tab-content [tabId]="1">Tab 1 Content</cats-ui-tab-content>
<cats-ui-tab-content [tabId]="2">Tab 2 Content</cats-ui-tab-content>
</cats-ui-tabset>TypeScript:
tabConfig = {
addTab: true, // Show "+" add tab button
closeTab: true, // Show close button on tabs
homeTab: true, // Enable a fixed home tab at ID 0
type: 'Stroke', // Tab style variant
};
tab1 = [
{ id: 1, title: 'Tab1' },
{
id: 2,
title: 'Tab2',
leadingIcon: 'images/command.svg',
tralingIocn: 'images/x-circle.svg',
count: 67,
},
];
activeTab: 1;
tab = 6; // counter for dynamic tab IDs
onTabAdded(ev: any) {
const newTab = {
id: ++this.tab,
title: `Dynamic Tab ${this.tab}`,
};
this.tab1 = [...this.tab1, newTab];
this.activeTab = newTab.id;
}
onTabClosed(id: number) {
console.log('Tab closed:', id);
}
activeTabChange(dt: any) {
console.log('Active tab:', dt);
}Tab item options:
| Property | Type | Description |
| ------------- | -------- | -------------------------------- |
| id | number | Unique tab ID |
| title | string | Tab label |
| leadingIcon | string | Icon path shown before the title |
| tralingIocn | string | Icon path shown after the title |
| count | number | Badge count shown on the tab |
WizardComponent — <cats-ui-wizard>
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.
Template:
<!-- Trigger button -->
<button (click)="openUserWizard()">Open User Wizard</button>
@if (wizard.isOpen('classification')()) {
<cats-ui-wizard wizardId="classification" title="Data Classification" [showProgressBar]="true" [showStepBadge]="true" (closed)="closeModal()">
<ng-template wizardStep>
<app-step-one></app-step-one>
</ng-template>
<ng-template wizardStep>
<app-step-two></app-step-two>
</ng-template>
<ng-template wizardStep>
<app-step-three></app-step-three>
</ng-template>
<ng-template wizardStep>
<app-step-four></app-step-four>
</ng-template>
</cats-ui-wizard>
}TypeScript:
import { WizardService } from "cats-ui-lib";
export class ParentComponent {
constructor(public wizard: WizardService) {}
openUserWizard() {
const wizardId = "classification";
// Define the step titles and initial states
this.wizard.stepConfig.update((config: any) => {
config[wizardId] = [
{ title: "User Info", state: "active" },
{ title: "Details", state: "normal" },
{ title: "Review", state: "normal" },
{ title: "Confirm", state: "normal" },
];
return config;
});
this.wizard.open(wizardId, { steps: [] });
}
closeModal() {
this.wizard.close("classification");
}
}Component inputs:
| Input | Type | Description |
| ----------------- | --------- | ----------------------------------------------------- |
| wizardId | string | Unique identifier matching the ID used in the service |
| title | string | Title displayed in the wizard header |
| showProgressBar | boolean | Show a progress bar across the top of the wizard |
| showStepBadge | boolean | Show a step counter badge (e.g. "Step 2 of 4") |
| expandable | boolean | Allow the wizard to be expanded to full screen |
Component outputs:
| Output | Type | Description |
| -------- | -------------------- | --------------------------------- |
| closed | EventEmitter<void> | Emitted when the wizard is closed |
WizardService API:
| Method / Property | Signature | Description |
| ----------------- | ------------------------------------------------ | ------------------------------------------------- |
| open() | open(id: string, options: { steps: [] }): void | Opens the wizard with the given ID |
| close() | close(id: string): void | Closes the wizard with the given ID |
| isOpen() | isOpen(id: string): Signal<boolean> | Returns a signal indicating if the wizard is open |
| stepConfig | WritableSignal<Record<string, StepConfig[]>> | Signal holding step definitions per wizard ID |
Step config object fields:
| Field | Type | Description |
| ------- | -------- | ------------------------------------------------- |
| title | string | Display label for the step in the progress bar |
| state | string | Initial state: 'active' (current) or 'normal' |
Notes:
- Each
<ng-template wizardStep>maps to a step in the order it appears. - The number of
<ng-template wizardStep>blocks should match the number of entries instepConfig. - The wizard uses Angular Signals internally; use
wizard.isOpen('id')()(note the call()) to read the signal value in templates.
CustomDatePickerComponent — <cats-ui-custom-date-picker>
Supports single, range, and dual modes with optional time selection.
| Mode | Description |
| -------- | ---------------------------------- |
| single | Single date picker (± time) |
| range | Start and end date picker (± time) |
| dual | Two-calendar view (± time) |
Template:
<!-- Single date + time -->
<cats-ui-custom-date-picker [config]="{ mode: 'single', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
<!-- Date range -->
<cats-ui-custom-date-picker [config]="{ mode: 'range', time: false, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
<!-- Date range + time -->
<cats-ui-custom-date-picker [config]="{ mode: 'range', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
<!-- Dual calendar -->
<cats-ui-custom-date-picker [config]="{ mode: 'dual', time: false, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>
<!-- Dual calendar + time -->
<cats-ui-custom-date-picker [config]="{ mode: 'dual', time: true, parentDateFormat: 'MM/dd/yyyy' }" (applied)="displayData($event)"> </cats-ui-custom-date-picker>Config options:
| Property | Type | Description |
| ------------------ | --------- | --------------------------------------------- |
| mode | string | 'single' | 'range' | 'dual' |
| time | boolean | Show time picker alongside the date |
| parentDateFormat | string | Output date format, e.g. 'MM/dd/yyyy' |
| minDate | Date | Minimum selectable date |
| maxDate | Date | Maximum selectable date |
| placeholder | string | Placeholder for single-date mode |
| fromPlaceholder | string | Placeholder for start date in range/dual mode |
| toPlaceholder | string | Placeholder for end date in range/dual mode |
| disabledDates | Date[] | Array of dates to disable |
| disablePastDays | number | Number of past days to disable |
| showDateLabel | boolean | Show label above date input |
| showTimeLabel | boolean | Show label above time input |
TimestampFilterComponent — <cats-ui-timestamp-filter>
A pre-built filter component with quick date presets, custom input, and date picker submenus.
Template:
<cats-ui-timestamp-filter [config]="timeFilterConfig" (selectionChange)="onFilterChange($event)"> </cats-ui-timestamp-filter>TypeScript:
timeFilterConfig = {
title: 'Timestamp Filter',
showReset: true,
options: [
{ label: 'Live', value: 'live' },
{ label: 'Today', value: 'today', default: true },
{ label: 'This Week', value: 'week' },
{ label: 'This Month', value: 'month' },
{ label: 'This Financial Year', value: 'fy' },
{ label: 'Last 24 Hours', value: '24h' },
{ label: 'Last 30 days', value: '30d' },
// Custom number input (e.g. "Last N days")
{ label: 'Last', value: 'last', type: 'input', custom: true },
// Date picker submenus
{
label: 'Custom Date',
value: 'date',
type: 'submenu',
custom: true,
pickerMode: 'single',
parentDateFormat: 'MM/dd/yyyy',
},
{
label: 'Custom Date and Time',
value: 'datetime',
type: 'submenu',
custom: true,
pickerMode: 'single',
parentDateFormat: 'MM/dd/yyyy',
},
{
label: 'Custom Date Range',
value: 'range',
type: 'submenu',
custom: true,
pickerMode: 'range',
},
{
label: 'Custom Date and Time Range',
value: 'datetimerange',
type: 'submenu',
custom: true,
},
],
};
onFilterChange(dt: any) {
console.log('timestamp filter', dt);
}Config options:
| Property | Type | Description |
| ----------- | --------- | ------------------------------ |
| title | string | Label shown above the filter |
| showReset | boolean | Show a reset button |
| options | array | Array of filter option objects |
Option object fields:
| Field | Type | Description |
| ------------------ | --------- | -------------------------------------------------------------- |
| label | string | Display label for the option |
| value | string | Emitted value on selection |
| default | boolean | Pre-select this option on load |
| type | string | 'input' for numeric entry, 'submenu' for date picker popup |
| custom | boolean | Marks as a custom/user-defined option |
| pickerMode | string | Date picker mode: 'single' | 'range' |
| parentDateFormat | string | Output date format for picker submenus |
Tooltip Directive — catsUiTooltip
Apply as an attribute on any HTML element.
<button catsUiTooltip="This is a tooltip">Hover me</button>📁 Project Structure
cats-ui-lib/
├── accordion/
├── auto-complete-multi-select/
├── auto-complete-single-select/
├── checkbox-button/
├── custom-date-picker/
├── date-time-picker/
├── input/
├── multi-select/
├── radio-button/
├── search-box/
├── single-select/
├── tabs/
├── tabset/
├── timestamp-filter/
├── toogle-button/
└── wizard/🔗 Links
- npm: https://www.npmjs.com/package/cats-ui-lib
- Angular CLI Docs: https://angular.dev/tools/cli
🛠️ Development
Build the library
ng build cats-uiRun unit tests
ng testPublish to npm
ng build cats-ui
cd dist/cats-ui
npm publish📋 Requirements
| Dependency | Version | | ---------- | ------- | | Angular | >= 19.x | | Node.js | >= 18.x |
📄 License
MIT © cats-ui-lib
