# Ngx-Library Utility Components and Pipes

This library provides a set of utility components and pipes for Angular applications.

## CaseConverter Pipe

The `CaseConverter` pipe transforms text into various case formats.

**Usage:**

```html
<p>{{ 'my text' | caseConverter }}</p>
<!-- Output: My Text (Title Case) -->
<p>{{ 'my text' | caseConverter:'LC' }}</p>
<!-- Output: my text (Lower Case) -->
```

**Arguments:**

-   `value`: The input string to transform.
-   `caseType`: (Optional) The desired case type. Defaults to 'TC' (Title Case). Possible values are:
    -   `LC`: Lower Case
    -   `UC`: Upper Case
    -   `CC`: Camel Case
    -   `NC`: No Change
    -   `TC`: Title Case

## CustomEventListener Class

The `CustomEventListener` class simplifies event management by adding and removing event listeners from an element. It also provides a mechanism to prevent duplicate event handler registrations.

**Usage:**

```typescript
import { CustomEventListener } from './custom-listener'; // Import

constructor(private elementRef: ElementRef, private renderer: Renderer2) {}

ngOnInit() {
  const popoverEventHandlers = new Map<string, Function>();
  popoverEventHandlers.set('click', this.onClick.bind(this));  // Add your handler
  popoverEventHandlers.set('mouseenter', this.onHover.bind(this));

  this.customEventListener = new CustomEventListener(this.elementRef, this.renderer);
  this.customEventListener.updateEventHandlers(popoverEventHandlers);
}

ngOnDestroy() {  // Remember to clean up listeners on component destroy
  this.customEventListener.updateEventHandlers(new Map()); // Removes all listeners
}

onClick(event: any) {
  // Handle click event
}

onHover(event: any) {
  // Handle mouseenter event
}

```

**Methods:**

-   `updateEventHandlers(popoverEventHandlers: Map<string, Function>): void`: Takes a map of event names and their corresponding handler functions. Adds listeners for new events, removes listeners for events no longer in the map, and updates existing listeners if the function has changed. Supported events are: 'mouseenter', 'mouseleave', 'click', 'init', 'shown', 'hidden'.
-   `addEvent(eventName: string, event: (e: any) => void)`: Adds an event listener to the element.
-   `removeEvent(eventName: string)`: Removes an event listener from the element.

## FileUploadComponent

The `FileUploadComponent` is a simple component to handle file uploads in Angular forms.

**Usage:**

```html
<file-upload [(ngModel)]="selectedFile" [multi]="true"></file-upload>

<button (click)="clearFileInput()">Clear File Input</button>
```

**Inputs:**

-   `multi`: (Optional, defaults to `false`) A boolean indicating whether multiple files can be selected.

**Outputs**: (Implicit via ControlValueAccessor/ngModel)

-   The selected `File` or `FileList` object will be updated in your ngModel variable.

**Methods:**

-   `clearInput()`: Clears the file input element and sets the bound value to null. This method is useful for resetting the file input programmatically.

**Example with Clearing the Input:**

```typescript
selectedFile: File | FileList | null = null;

clearFileInput() {
    const fileUploadComponent = this.fileUploadComponentRef.nativeElement;  // Get a reference to the component (e.g., using a template reference variable).
    fileUploadComponent.clearInput(); // Call clearInput on the component instance
    this.selectedFile = null; // Update bound variable, necessary if not using ngModel directly
  }
```

## Utility Functions

-   `stringifyMap(map: Map<string, Function | null> | undefined): string`: Converts a map of event handlers to a string representation, useful for comparing map contents for changes. Used internally by `CustomEventListener`.

# Ngx-Library Utility Directives and Pipes

This library provides a set of utility directives and pipes for Angular applications.

## FilterPipe

The `FilterPipe` filters an array of objects based on a search string and specified search keys. It supports filtering nested objects as well.

**Usage:**

```html
<li *ngFor="let item of items | filterPipe: searchText: searchKey">...</li>
<li *ngFor="let item of items | filterPipe: searchText: ['name', 'description']">...</li>
<li *ngFor="let item of nestedItems | filterPipe: searchText: 'name': true">...</li>
```

```

**Arguments:**

-   `value`: The input array of objects.
-   `searchText`: The string to search for.
-   `searchKey`: (Optional) A string or array of strings representing the property keys to search within the objects. If omitted, the entire object string representation will be searched.
-   `nested`: (Optional, defaults to `false`). If true and `searchKey` is a string, performs nested filtering on objects with a `children` property.

```

## InputMaskDirective

The `InputMaskDirective` provides input masking and validation for number inputs.

**Usage:**

```html
<input type="text" inputMask [mask]="'0,000.00'" [decimal]="2" [(ngModel)]="myValue" />
```

```
**Inputs:**

-   `mask`: (Optional) The desired mask format (e.g., '0,000.00'). Defaults to no masking.
-   `decimal`: (Optional) The number of decimal places allowed. Defaults to 0.
-   `delimitter`: (Optional) The delimiter to use (e.g., ','). Defaults to ','.
-   `maxLength`: (Optional) The maximum number of digits allowed (including decimal places and delimiters). Defaults to 100.
-   `clearZero`: (Optional) Whether to clear the input value if it is zero on blur. Defaults to false.
-   `maxValue`: (Optional) The maximum numeric value allowed.
-   `removeMask`: (Optional) Whether to remove the mask from the output value on blur. Defaults to false.

```

## KeyPressValidatorDirective

The `KeyPressValidatorDirective` allows or restricts specific key presses based on a regular expression pattern.

**Usage:**

```html
<input type="text" keyPressValidator [regexPattern]="'^[a-zA-Z0-9]*$'" [KeyPressType]="'Allow'" />
<!-- Only alphanumeric -->
<input type="text" keyPressValidator [regexPattern]="'^[0-9]*$'" [KeyPressType]="'Restrict'" />
<!-- Restrict Numbers -->
```

```
**Inputs:**

-   `regexPattern`: The regular expression pattern to match against key presses.
-   `KeyPressType`: (Optional, defaults to 'Allow') Whether to 'Allow' or 'Restrict' key presses matching the pattern.
-   `removePattern`: (Optional) Regex pattern to remove characters from input.

```

## OutsideClickDirective

The `OutsideClickDirective` detects clicks outside of the element it's attached to.

**Usage:**

```html
<div outSideClick (clickOutside)="closeDropdown()">
	<!-- Dropdown content -->
</div>
```

```
**Outputs:**

-   `clickOutside`: Emits an event when a click occurs outside of the host element.

```

## PopoverDirective

The `PopoverDirective` creates customizable popovers that can be triggered by clicks or hovers. It uses the `@ngxhelpers/overlay` library for overlay management and leverages the `popover.scss` file for styling.

**Installation:**

Make sure you have `@ngxhelpers/overlay` installed:

```bash
npm install @ngxhelpers/overlay
npm install @ngxhelpers/utils
```

**Usage:**

1. **Import and add `PopoverDirective` to your component's `imports` array:**

    ```typescript
    import { PopoverDirective } from '@ngxhelpers/utils';

    @Component({
        // ...
        standalone: true,
        imports: [PopoverDirective, ..., // other imports
        // ...
    })
    export class MyComponent { }

    ```

2. **Apply the directive to an element:**

    ```html
    <button customPopover [popover]="popoverTemplate" [trigger]="'click'" [popoverContext]="{ name: 'John Doe' }">
    	Open Popover
    </button>

    <ng-template #popoverTemplate let-data="data">Hello, {{ data.name }}!</ng-template>
    ```

**Styling:**

```json
// in angular.json
{
  "styles": [
    "node_modules/@ngxhelpers/utils/assets/popover.css",
    ...
  ]
}

```

The popover's appearance is controlled by the `popover.scss` file, which is located in the `assets` folder of the `utils` project. You can customize the styles in this file to match your application's theme. The following classes are applied to the popover:

-   `custom-popover`: Applied to the popover content itself.
-   `custom-popover-backdrop`: Applied to the backdrop (if enabled via `popoverOptions`).
-   For positioning, one of the following classes is also added:
    -   `right-bottom`
    -   `right-top`
    -   `left-top`
    -   `left-bottom`

You can modify or extend these classes in your application's styles.

```
**Inputs:**

-   `id`: (Optional) A unique ID for the popover. Defaults to '\_popover'.
-   `popover`: Content of the popover. Can be a `TemplateRef`, a `ComponentType`, an `HTMLElement`, a string, or an ElementRef.
-   `popoverOption`: (Optional) Configuration options for the overlay, following the `NgxOverlayConfigOptions` interface from `@ngxhelpers/overlay`. See `@ngxhelpers/overlay` documentation for details.
-   `popoverOrigin`: (Optional) The origin element for positioning the popover. Defaults to the host element if not provided.
-   `popoverContext`: (Optional) An object that will be passed as data to the popover template or component. Useful for passing dynamic values.
-   `triggers`: (Optional) The trigger for opening and closing the popover:
    -   `'click'`: Opens on click, closes on clicking outside.
    -   `'hover'`: Opens on mouseenter, closes on mouseleave. Defaults to `'hover'`.
-   `popoverEventHandlers`: (Optional) A map of event names (strings) and handler functions. Useful for adding custom event logic to the popover. The following event types are supported:
    -   `'mouseenter'`: Triggered when the mouse enters the popover trigger element.
    -   `'mouseleave'`: Triggered when the mouse leaves the popover trigger element.
    -   `'click'`: Triggered when the popover trigger element is clicked.
    -   `'shown'`: Triggered when the popover is displayed. The event value is an object: `{ success: true, elm: NgxOverlayRef }`.
    -   `'hidden'`: Triggered when the popover is closed. The event value is an object: `{ success: true }`.
```

## Example with Event Handlers

```typescript
import { Component } from '@angular/core';

// ... other imports

@Component({
    selector: 'app-my-component',
    template: `
      <button customPopover
              [popover]="popoverTemplate"
              [trigger]="'click'"
              [popoverEventHandlers]="eventHandlers">
          Open Popover
      </button>
      <ng-template #popoverTemplate>Popover Content</ng-template>
    `,
    imports: [PopoverDirective],
    standalone: true
})
export class MyComponent {
    eventHandlers = new Map([
        ['shown', (event: any) => {
            console.log('Popover shown', event); // Logs the 'shown' event data
        }],
        ['hidden', (event: any) => {
            console.log('Popover hidden', event); // Logs the 'hidden' event data
        }
    );
}

```

```
**Output / Public Methods**

-   `hide()`: Closes the popover programmatically.
```
