npm package: @stardyn/angular-ui-actions
Description: Angular UI Actions Package - Lightweight, configurable action components (modals, drawers, dialogs, loading) for Angular applications
Author: Stardyn Team
Latest version: 2.0.20

# @stardyn/angular-ui-actions

Lightweight, configurable action components (modals, drawers, dialogs, loading) for Angular applications. Provides advanced UI action features with minimal performance impact.

## Features

- **Modal Component**: Customizable modal dialogs with drag support
- **Drawer Component**: Slide-in drawers with customizable themes
- **Dialog Component**: Simple confirmation and alert dialogs
- **Loading Component**: Beautiful loading overlays
- **Theme Support**: Dark, Light, and Red themes
- **Content Projection**: Flexible content and footer projection
- **TypeScript Support**: Full type safety and intellisense
- **Performance Focused**: Optimized for production use
- **Responsive Design**: Mobile-friendly components

## Installation

```bash
npm install @stardyn/angular-ui-actions
```

## Quick Start

### 1. Service Usage

```typescript
import { Component, ViewContainerRef } from '@angular/core';
import { XConUIActionsService, ActionTheme } from '@stardyn/angular-ui-actions';

@Component({
  selector: 'app-root',
  template: `
    <h1>{{ title }}</h1>
    <button (click)="showModal()">Show Modal</button>
    <button (click)="showDrawer()">Show Drawer</button>
    <button (click)="showDialog()">Show Dialog</button>
    <button (click)="showLoader()">Show Loader</button>
  `
})
export class AppComponent {
  title = 'My Stardyn App';

  constructor(
    private actionsService: XConUIActionsService,
    private viewContainerRef: ViewContainerRef
  ) {
    this.actionsService.setViewContainerRef(this.viewContainerRef);
    this.actionsService.setTheme(ActionTheme.LIGHT);
  }

  showModal() {
    this.actionsService.openModal({
      title: 'Test Modal',
      width: '500px',
      height: '400px',
      closable: true,
      backdrop: true,
      component: MyModalContentComponent,
      data: { message: 'Hello from modal!' }
    }, (success, data) => {
      console.log('Modal closed:', success, data);
    });
  }

  showDrawer() {
    this.actionsService.openDrawer({
      title: 'Test Drawer',
      width: '400px',
      showCloseButton: true,
      showBackButton: true,
      component: MyDrawerContentComponent,
      data: { items: ['Item 1', 'Item 2', 'Item 3'] }
    }, (success, data) => {
      console.log('Drawer closed:', success, data);
    });
  }

  showDialog() {
    this.actionsService.showMessage(
      'Are you sure you want to delete this item?',
      ActionDialogType.YesNo,
      (accepted, data) => {
        console.log('Dialog result:', accepted);
      },
      { ok: 'Yes', cancel: 'No' }
    );
  }

  showLoader() {
    this.actionsService.showLoader('Processing...');
    
    setTimeout(() => {
      this.actionsService.hideLoader();
    }, 3000);
  }
}
```

### 2. Modal Content Component

```typescript
import { Component } from '@angular/core';
import { XConUIActionModalBase } from '@stardyn/angular-ui-actions';

@Component({
  selector: 'app-modal-content',
  template: `
    <action-modal-content>
      <div style="padding: 20px;">
        <h3>Modal Content</h3>
        <p>{{ getValue('message', 'Default message') }}</p>
        <button (click)="doSomething()">Do Something</button>
      </div>
    </action-modal-content>
    
    <action-modal-footer>
      <div style="padding: 16px; text-align: right;">
        <button (click)="close()" style="margin-right: 8px;">Cancel</button>
        <button (click)="save()">Save</button>
      </div>
    </action-modal-footer>
  `
})
export class MyModalContentComponent extends XConUIActionModalBase {
  
  doSomething() {
    this.showLoader('Processing...');
    
    setTimeout(() => {
      this.hideLoader();
      this.setValue('result', 'Operation completed');
    }, 2000);
  }

  save() {
    const result = this.getValue('result', null);
    this.closeWithData({ success: true, result });
  }

  onClose() {
    // Called when X button is clicked
    this.close();
  }
}
```

### 3. Drawer Content Component

```typescript
import { Component } from '@angular/core';
import { XConUIActionDrawerBase } from '@stardyn/angular-ui-actions';

@Component({
  selector: 'app-drawer-content',
  template: `
    <action-drawer-content>
      <div style="padding: 20px;">
        <h3>Drawer Content</h3>
        <ul>
          <li *ngFor="let item of getValue('items', [])">{{ item }}</li>
        </ul>
      </div>
    </action-drawer-content>
    
    <action-drawer-footer>
      <div style="padding: 16px; text-align: right;">
        <button (click)="close()" style="margin-right: 8px;">Close</button>
        <button (click)="selectAll()">Select All</button>
      </div>
    </action-drawer-footer>
  `
})
export class MyDrawerContentComponent extends XConUIActionDrawerBase {
  
  selectAll() {
    const items = this.getValue('items', []);
    this.closeWithData({ selectedItems: items });
  }

  onClose() {
    // Called when X button is clicked
    this.close();
  }
}
```

## API Reference

### XConUIActionsService

#### Configuration

```typescript
// Set theme globally
setTheme(theme: ActionTheme): void

// Set view container ref (required)
setViewContainerRef(viewContainerRef: ViewContainerRef): void
```

#### Modal Methods

```typescript
interface XConUIActionModalSettings {
  title?: string;
  movable?: boolean;
  backdrop?: boolean;
  closable?: boolean;
  shadow?: boolean;
  component?: any;
  width?: number | string;
  height?: number | string;
  data?: any;
  theme?: ActionTheme;
}

openModal(settings: XConUIActionModalSettings, onAction?: OnAction): void
```

#### Drawer Methods

```typescript
interface XConUIActionDrawerSettings {
  title?: string;
  showCloseButton?: boolean;
  showCloseButtonWithConfirm?: boolean;
  showBackButton?: boolean;
  showOverlay?: boolean;
  component?: any;
  data?: any;
  cssClass?: string;
  width?: string;
  topPadding?: string;
  onBackClick?: () => void;
  zIndex?: number;
  theme?: ActionTheme;
}

openDrawer(settings: XConUIActionDrawerSettings, onAction?: OnAction): XConUIActionDrawerComponent | null
```

#### Dialog Methods

```typescript
enum ActionDialogType {
  None = 0,
  YesNo = 2
}

interface DialogOptions {
  ok?: string;
  cancel?: string;
  theme?: ActionTheme;
}

showMessage(
  message: string,
  actionType?: ActionDialogType,
  onAction?: OnAction,
  options?: DialogOptions
): void
```

#### Loading Methods

```typescript
interface LoaderOptions {
  message?: string;
  theme?: ActionTheme;
}

showLoader(options?: LoaderOptions | string): void
hideLoader(): void
```

### Base Classes

#### XConUIActionModalBase

```typescript
abstract class XConUIActionModalBase {
  data: any;
  baseModal: XConUIActionModalComponent;
  
  getValue(key: string, def: any): any;
  setValue(key: string, value: any): void;
  showLoader(message: string): void;
  hideLoader(): void;
  close(): void;
  closeWithData(item: any): void;
  onClose(): void; // Override this method
}
```

#### XConUIActionDrawerBase

```typescript
abstract class XConUIActionDrawerBase {
  data: any;
  baseDrawer: XConUIActionDrawerComponent;
  
  getValue(key: string, def: any): any;
  setValue(key: string, value: any): void;
  showLoader(message: string): void;
  hideLoader(): void;
  close(): void;
  closeWithData(item: any): void;
  onClose(): void; // Override this method
}
```

### Content Projection Components

```typescript
// For modals
<action-modal-content>
  <!-- Your modal content here -->
</action-modal-content>

<action-modal-footer>
  <!-- Your modal footer here -->
</action-modal-footer>

// For drawers
<action-drawer-content>
  <!-- Your drawer content here -->
</action-drawer-content>

<action-drawer-footer>
  <!-- Your drawer footer here -->
</action-drawer-footer>
```

### Themes

```typescript
enum ActionTheme {
  DARK = 'dark',   // Default dark theme
  LIGHT = 'light', // Light theme
  RED = 'red'      // Red accent theme
}
```

## Usage Examples

### Complex Modal with Form

```typescript
@Component({
  template: `
    <action-modal-content>
      <form [formGroup]="userForm" style="padding: 20px;">
        <h3>Edit User</h3>
        
        <div style="margin-bottom: 16px;">
          <label>Name:</label>
          <input formControlName="name" style="width: 100%; padding: 8px;">
        </div>
        
        <div style="margin-bottom: 16px;">
          <label>Email:</label>
          <input formControlName="email" type="email" style="width: 100%; padding: 8px;">
        </div>
      </form>
    </action-modal-content>
    
    <action-modal-footer>
      <div style="padding: 16px; text-align: right; border-top: 1px solid #eee;">
        <button (click)="close()" style="margin-right: 8px;">Cancel</button>
        <button (click)="saveUser()" [disabled]="userForm.invalid">Save</button>
      </div>
    </action-modal-footer>
  `
})
export class EditUserModalComponent extends XConUIActionModalBase implements OnInit {
  userForm!: FormGroup;

  ngOnInit() {
    const user = this.getValue('user', {});
    this.userForm = new FormGroup({
      name: new FormControl(user.name || '', Validators.required),
      email: new FormControl(user.email || '', [Validators.required, Validators.email])
    });
  }

  saveUser() {
    if (this.userForm.valid) {
      this.showLoader('Saving user...');
      
      // Simulate API call
      setTimeout(() => {
        this.hideLoader();
        this.closeWithData({
          success: true,
          user: this.userForm.value
        });
      }, 1000);
    }
  }
}
```

### Drawer with Navigation

```typescript
@Component({
  template: `
    <action-drawer-content>
      <div style="padding: 20px;">
        <h3>Settings</h3>
        
        <div style="margin-bottom: 16px;">
          <button (click)="showSection('profile')" style="width: 100%; padding: 12px; margin-bottom: 8px;">
            Profile Settings
          </button>
          <button (click)="showSection('security')" style="width: 100%; padding: 12px; margin-bottom: 8px;">
            Security Settings
          </button>
          <button (click)="showSection('notifications')" style="width: 100%; padding: 12px;">
            Notification Settings
          </button>
        </div>
        
        <div [ngSwitch]="currentSection">
          <div *ngSwitchCase="'profile'">
            <h4>Profile Settings</h4>
            <p>Profile configuration options...</p>
          </div>
          <div *ngSwitchCase="'security'">
            <h4>Security Settings</h4>
            <p>Security configuration options...</p>
          </div>
          <div *ngSwitchCase="'notifications'">
            <h4>Notification Settings</h4>
            <p>Notification preferences...</p>
          </div>
        </div>
      </div>
    </action-drawer-content>
  `
})
export class SettingsDrawerComponent extends XConUIActionDrawerBase {
  currentSection = 'profile';

  showSection(section: string) {
    this.currentSection = section;
  }
}
```

## Styling

The components come with built-in themes but can be customized:

```css
/* Custom modal styling */
xcon-ui-actions-modal .xcon-modal-content {
  border-radius: 12px !important;
}

/* Custom drawer styling */
xcon-ui-actions-drawer .xcon-drawer-container {
  box-shadow: -8px 0 16px rgba(0, 0, 0, 0.2) !important;
}

/* Custom dialog styling */
xcon-ui-actions-dialogs .xcon-dialog-content {
  border-radius: 8px !important;
}
```

## Performance

- **Lazy Loading**: Components are only loaded when needed
- **Memory Friendly**: Proper cleanup on component destroy
- **Optimized**: Minimal DOM manipulation
- **Production Ready**: Tree-shakable and AOT compatible

## TypeScript Support

Full TypeScript support with strict typing:

```typescript
import {
    XConUIActionsService,
    XConUIActionModalSettings,
    XConUIActionDrawerSettings,
    ActionTheme,
    OnAction
} from '@stardyn/angular-ui-actions';

// Type-safe configuration
const modalSettings: XConUIActionModalSettings = {
    title: 'My Modal',
    width: 500,
    height: '400px',
    theme: ActionTheme.LIGHT
};

// Type-safe callback
const onAction: OnAction = (success: boolean, data: any) => {
    console.log('Action completed:', success, data);
};
```