# Base Functions Library - Complete Documentation

## Table of Contents
- [Overview](#overview)
- [Installation](#installation)
- [Pipes](#pipes)
- [Components](#components)
- [Usage Examples](#usage-examples)

---

## Overview

The `ngx-st-base-functions` library provides utility pipes and base components for common Angular tasks:

**Pipes:**
- `stCheckEmptyString`: Displays "- - -" for empty/null values
- `stSafeHtml`: Sanitizes HTML content for safe display
- `stSafe`: Bypasses security for URLs
- `stCutText`: Truncates text to specified length

**Components:**
- `StSubscribeDestroyComponent`: Base component for automatic subscription cleanup
- `LoaderComponent`: Loading spinner component

---

## Installation

```bash
npm install ngx-st-base-functions
```

Import the module:

```typescript
import { StBaseFunctionsModule } from 'ngx-st-base-functions';

@NgModule({
  imports: [StBaseFunctionsModule]
})
export class AppModule { }
```

---

## Pipes

### `stCheckEmptyString`
Displays "- - -" for null, undefined, or empty values.

**Input:** `any`  
**Output:** Original value or "- - -"

**Example:**
```html
<p>{{ user.middleName | stCheckEmptyString }}</p>
<!-- Output: "John" or "- - -" if empty -->

<p>{{ user.phone | stCheckEmptyString }}</p>
<!-- Output: "+1234567890" or "- - -" if null -->
```

### `stSafeHtml`
Sanitizes HTML content for safe display in templates.

**Input:** `string`  
**Output:** `SafeHtml`

**Example:**
```html
<div [innerHTML]="htmlContent | stSafeHtml"></div>
<!-- Safely renders HTML content -->

<p [innerHTML]="description | stSafeHtml"></p>
<!-- Renders: <strong>Bold text</strong> safely -->
```

### `stSafe`
Bypasses Angular security for trusted URLs (use with caution).

**Input:** `string`  
**Output:** `SafeResourceUrl`

**Example:**
```html
<iframe [src]="videoUrl | stSafe"></iframe>
<!-- Allows embedding external URLs -->
```

### `stCutText`
Truncates text to specified length and adds ellipsis.

**Input:** `string`  
**Parameter:** `maxLength: number`  
**Output:** Truncated string with "..."

**Example:**
```html
<p>{{ longText | stCutText:50 }}</p>
<!-- Output: "This is a very long text that will be tru..." -->

<p>{{ description | stCutText:100 }}</p>
<!-- Limits to 100 characters -->
```

---

## Components

### `StSubscribeDestroyComponent`
Base component that automatically unsubscribes from observables on component destruction.

**Usage:**
```typescript
import { StSubscribeDestroyComponent } from 'ngx-st-base-functions';

@Component({...})
export class MyComponent extends StSubscribeDestroyComponent implements OnInit {
  
  ngOnInit(): void {
    // Subscriptions are automatically cleaned up
    this.userService.getUsers()
      .pipe(takeUntil(this.destroyed$))
      .subscribe(users => {
        this.users = users;
      });
  }
}
```

**Features:**
- Provides `destroyed$` Subject
- Automatically completes `destroyed$` on component destroy
- Prevents memory leaks from subscriptions

### `LoaderComponent`
Displays a loading spinner.

**Usage:**
```html
<st-loader *ngIf="loading"></st-loader>
```

---

## Usage Examples

### Example 1: Display User Data with Empty Checks

```typescript
@Component({
  template: `
    <div class="user-details">
      <p>First Name: {{ user.firstName | stCheckEmptyString }}</p>
      <p>Middle Name: {{ user.middleName | stCheckEmptyString }}</p>
      <p>Last Name: {{ user.lastName | stCheckEmptyString }}</p>
      <p>Phone: {{ user.phone | stCheckEmptyString }}</p>
      <p>Email: {{ user.email | stCheckEmptyString }}</p>
    </div>
  `
})
export class UserDetailsComponent {
  user = {
    firstName: 'John',
    middleName: '',  // Will show "- - -"
    lastName: 'Doe',
    phone: null,  // Will show "- - -"
    email: 'john@example.com'
  };
}
```

### Example 2: Display HTML Content

```typescript
@Component({
  template: `
    <div class="article">
      <h2>{{ article.title }}</h2>
      <div [innerHTML]="article.content | stSafeHtml"></div>
      <p class="excerpt">{{ article.content | stCutText:200 }}</p>
    </div>
  `
})
export class ArticleComponent {
  article = {
    title: 'My Article',
    content: '<p>This is <strong>HTML</strong> content with <em>formatting</em>.</p>'
  };
}
```

### Example 3: Table with Empty Value Handling

```typescript
@Component({
  template: `
    <table>
      <tr *ngFor="let item of items">
        <td>{{ item.code | stCheckEmptyString }}</td>
        <td>{{ item.name | stCheckEmptyString }}</td>
        <td>{{ item.description | stCutText:50 }}</td>
        <td>{{ item.notes | stCheckEmptyString }}</td>
      </tr>
    </table>
  `
})
export class ItemsTableComponent {
  items = [
    { code: 'A001', name: 'Item 1', description: 'Long description...', notes: '' },
    { code: 'A002', name: 'Item 2', description: 'Another desc...', notes: null }
  ];
}
```

### Example 4: Component with Auto-Cleanup

```typescript
import { StSubscribeDestroyComponent } from 'ngx-st-base-functions';
import { takeUntil } from 'rxjs/operators';

@Component({
  template: `
    <st-loader *ngIf="loading"></st-loader>
    <div *ngIf="!loading">
      <div *ngFor="let user of users">
        {{ user.name }}
      </div>
    </div>
  `
})
export class UsersComponent extends StSubscribeDestroyComponent implements OnInit {
  users: User[] = [];
  loading = true;
  
  constructor(private userService: UserService) {
    super();
  }
  
  ngOnInit(): void {
    // Subscription automatically cleaned up on destroy
    this.userService.getUsers()
      .pipe(takeUntil(this.destroyed$))
      .subscribe(users => {
        this.users = users;
        this.loading = false;
      });
    
    // Multiple subscriptions all cleaned up
    this.userService.getUserUpdates()
      .pipe(takeUntil(this.destroyed$))
      .subscribe(update => {
        this.handleUpdate(update);
      });
  }
  
  handleUpdate(update: any): void {
    // Handle real-time updates
  }
}
```

### Example 5: Embed External Content

```typescript
@Component({
  template: `
    <div class="video-container">
      <iframe 
        [src]="videoUrl | stSafe" 
        frameborder="0" 
        allowfullscreen>
      </iframe>
    </div>
  `
})
export class VideoPlayerComponent {
  videoUrl = 'https://www.youtube.com/embed/VIDEO_ID';
}
```

### Example 6: Card with Truncated Description

```typescript
@Component({
  template: `
    <mat-card *ngFor="let product of products">
      <mat-card-title>{{ product.name }}</mat-card-title>
      <mat-card-content>
        <p>{{ product.description | stCutText:100 }}</p>
        <p>SKU: {{ product.sku | stCheckEmptyString }}</p>
        <p>Category: {{ product.category | stCheckEmptyString }}</p>
      </mat-card-content>
    </mat-card>
  `
})
export class ProductCardsComponent {
  products = [
    {
      name: 'Product 1',
      description: 'This is a very long product description that needs to be truncated...',
      sku: 'SKU-001',
      category: ''
    }
  ];
}
```

### Example 7: Loading State Management

```typescript
@Component({
  template: `
    <div class="content-wrapper">
      <st-loader *ngIf="loading"></st-loader>
      
      <div *ngIf="!loading && data">
        <h2>{{ data.title }}</h2>
        <div [innerHTML]="data.content | stSafeHtml"></div>
      </div>
      
      <div *ngIf="!loading && !data" class="no-data">
        No data available
      </div>
    </div>
  `
})
export class DataViewComponent implements OnInit {
  loading = true;
  data: any;
  
  ngOnInit(): void {
    this.loadData();
  }
  
  loadData(): void {
    this.loading = true;
    this.dataService.getData().subscribe(
      data => {
        this.data = data;
        this.loading = false;
      },
      error => {
        this.loading = false;
      }
    );
  }
}
```

---

## Best Practices

1. **Use `stCheckEmptyString` for optional fields**:
   ```html
   {{ user.middleName | stCheckEmptyString }}
   ```

2. **Extend `StSubscribeDestroyComponent` for components with subscriptions**:
   ```typescript
   export class MyComponent extends StSubscribeDestroyComponent {
     // Automatic cleanup
   }
   ```

3. **Always use `takeUntil(this.destroyed$)` with subscriptions**:
   ```typescript
   this.service.getData()
     .pipe(takeUntil(this.destroyed$))
     .subscribe(...)
   ```

4. **Use `stSafeHtml` when displaying user-generated HTML**:
   ```html
   <div [innerHTML]="content | stSafeHtml"></div>
   ```

5. **Truncate long text in lists and cards**:
   ```html
   {{ description | stCutText:150 }}
   ```

---

## Security Note

**`stSafe` pipe**: Use with caution. Only use with trusted URLs as it bypasses Angular's security. Never use with user-generated content.

**`stSafeHtml` pipe**: Sanitizes HTML but still use carefully with user-generated content.

---

This library provides essential utilities for handling common Angular development tasks.

