# Shaqra DGA PlatformsCode Angular Library

[![npm version](https://badge.fury.io/js/shaqra-dga-platformscode-angular.svg)](https://www.npmjs.com/package/shaqra-dga-platformscode-angular)
[![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)

A comprehensive Angular component library for building modern web applications. This library provides a collection of reusable, accessible, and customizable Angular components that integrate seamlessly with the DGA Design System.

## 🚀 Quick Start

### Installation

Install the library and its peer dependency:

```bash
npm install shaqra-dga-platformscode-angular @platformscode/core@0.0.17
```

### Basic Setup

#### For Module-based Angular Apps

1. **Import the module** in your `app.module.ts`:

```typescript
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ShaqraDgaPlatformscodeAngularModule } from 'shaqra-dga-platformscode-angular';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ShaqraDgaPlatformscodeAngularModule  // Add this
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],  // Important: Add this
  bootstrap: [AppComponent]
})
export class AppModule { }
```

2. **Use components** in your templates:

```html
<!-- app.component.html -->
<shaqra-dga-button variant="primary" (clicked)="handleClick()">
  Click Me
</shaqra-dga-button>

<shaqra-dga-text-input 
  label="Username" 
  placeholder="Enter your username"
  [(ngModel)]="username">
</shaqra-dga-text-input>
```

#### For Standalone Angular Apps

```typescript
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ShaqraDgaPlatformscodeAngularModule } from 'shaqra-dga-platformscode-angular';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ShaqraDgaPlatformscodeAngularModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <shaqra-dga-button variant="primary">Standalone Button</shaqra-dga-button>
  `
})
export class AppComponent { }
```

## 📚 Available Components

This library includes 7 production-ready components:

### 1. Button Component (`shaqra-dga-button`)
A customizable button component with multiple variants and states.

**Features:**
- Multiple variants: primary, neutral, danger
- Size options: small, medium, large
- Loading and disabled states
- Icon support

### 2. Text Input Component (`shaqra-dga-text-input`)
A flexible text input field with form control support.

**Features:**
- Form control integration (ControlValueAccessor)
- Label and placeholder support
- Required field validation
- Disabled state

### 3. Dropdown Component (`shaqra-dga-dropdown`)
A searchable dropdown select component.

**Features:**
- Keyboard navigation
- Custom options with labels and values
- Disabled options support
- Form control integration

### 4. Content Switcher Component (`shaqra-dga-content-switcher`)
A tab-like component for switching between different content views.

**Features:**
- Multiple variant styles
- Disabled items support
- Auto-selection of first item
- Selection change events

### 5. Single Date Picker Component (`shaqra-dga-single-datepicker`)
A calendar-based date picker for selecting single dates.

**Features:**
- Calendar view with month/year navigation
- Min/max date constraints
- Date formatting
- Keyboard accessibility

### 6. Ranged Date Picker Component (`shaqra-dga-ranged-datepicker`)
A date range picker for selecting start and end dates.

**Features:**
- Visual range selection
- Min/max date constraints
- Date range validation
- Form control integration

### 7. File Uploader Component (`shaqra-dga-file-uploader`)
A drag-and-drop file upload component.

**Features:**
- Drag and drop support
- File type validation
- File size limits
- Multiple file uploads
- Upload limit constraints

## 🎯 Usage Examples

### Button Component

```typescript
// component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html'
})
export class DemoComponent {
  onButtonClick() {
    console.log('Button clicked!');
  }
}
```

```html
<!-- component.html -->
<!-- Primary button -->
<shaqra-dga-button 
  variant="primary" 
  size="large"
  (clicked)="onButtonClick()">
  Submit
</shaqra-dga-button>

<!-- Neutral button -->
<shaqra-dga-button 
  variant="neutral" 
  size="medium">
  Cancel
</shaqra-dga-button>

<!-- Danger button -->
<shaqra-dga-button 
  variant="danger" 
  size="small"
  [disabled]="true">
  Delete
</shaqra-dga-button>

<!-- Loading button -->
<shaqra-dga-button 
  variant="primary"
  [loading]="isLoading">
  Processing...
</shaqra-dga-button>
```

### Text Input Component

```typescript
// component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-form',
  templateUrl: './form.component.html'
})
export class FormComponent {
  username: string = '';
  email: string = '';
  password: string = '';
}
```

```html
<!-- component.html -->
<shaqra-dga-text-input
  label="Username"
  placeholder="Enter your username"
  [(value)]="username"
  [required]="true">
</shaqra-dga-text-input>

<shaqra-dga-text-input
  label="Email"
  placeholder="Enter your email"
  type="email"
  [(value)]="email">
</shaqra-dga-text-input>

<shaqra-dga-text-input
  label="Password"
  placeholder="Enter your password"
  type="password"
  [(value)]="password"
  [disabled]="false">
</shaqra-dga-text-input>
```

### Dropdown Component

```typescript
// component.ts
import { Component } from '@angular/core';
import { DropdownOption } from 'shaqra-dga-platformscode-angular';

@Component({
  selector: 'app-dropdown-demo',
  templateUrl: './dropdown-demo.component.html'
})
export class DropdownDemoComponent {
  selectedCountry: any = null;
  
  countries: DropdownOption[] = [
    { value: 'sa', label: 'Saudi Arabia' },
    { value: 'ae', label: 'United Arab Emirates' },
    { value: 'kw', label: 'Kuwait' },
    { value: 'bh', label: 'Bahrain', disabled: true },
    { value: 'om', label: 'Oman' }
  ];

  onCountryChange(option: DropdownOption | null) {
    console.log('Selected country:', option);
  }
}
```

```html
<!-- component.html -->
<shaqra-dga-dropdown
  label="Select Country"
  placeholder="Choose a country"
  [options]="countries"
  [(value)]="selectedCountry"
  (selectionChange)="onCountryChange($event)">
</shaqra-dga-dropdown>
```

### Content Switcher Component

```typescript
// component.ts
import { Component } from '@angular/core';
import { ContentSwitcherItem } from 'shaqra-dga-platformscode-angular';

@Component({
  selector: 'app-switcher-demo',
  templateUrl: './switcher-demo.component.html'
})
export class SwitcherDemoComponent {
  currentView: string | number = 'overview';
  
  viewItems: ContentSwitcherItem[] = [
    { id: 'overview', label: 'Overview' },
    { id: 'details', label: 'Details' },
    { id: 'settings', label: 'Settings' },
    { id: 'archive', label: 'Archive', disabled: true }
  ];

  onViewChange(item: ContentSwitcherItem) {
    this.currentView = item.id;
    console.log('Current view:', item.label);
  }
}
```

```html
<!-- component.html -->
<shaqra-dga-content-switcher
  [items]="viewItems"
  [selectedId]="currentView"
  variant="primary"
  (selectionChange)="onViewChange($event)">
</shaqra-dga-content-switcher>

<div [ngSwitch]="currentView">
  <div *ngSwitchCase="'overview'">Overview content</div>
  <div *ngSwitchCase="'details'">Details content</div>
  <div *ngSwitchCase="'settings'">Settings content</div>
</div>
```

### Single Date Picker Component

```typescript
// component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-datepicker-demo',
  templateUrl: './datepicker-demo.component.html'
})
export class DatepickerDemoComponent {
  selectedDate: Date | null = null;
  minDate: Date = new Date(2020, 0, 1);
  maxDate: Date = new Date(2030, 11, 31);

  onDateSelected(date: Date | null) {
    console.log('Selected date:', date);
  }
}
```

```html
<!-- component.html -->
<shaqra-dga-single-datepicker
  label="Select Date"
  placeholder="DD/MM/YY"
  [(value)]="selectedDate"
  [minDate]="minDate"
  [maxDate]="maxDate"
  (dateChange)="onDateSelected($event)">
</shaqra-dga-single-datepicker>
```

### Ranged Date Picker Component

```typescript
// component.ts
import { Component } from '@angular/core';
import { DateRange } from 'shaqra-dga-platformscode-angular';

@Component({
  selector: 'app-range-picker-demo',
  templateUrl: './range-picker-demo.component.html'
})
export class RangePickerDemoComponent {
  dateRange: DateRange = { startDate: null, endDate: null };

  onRangeChange(range: DateRange) {
    console.log('Start:', range.startDate);
    console.log('End:', range.endDate);
  }
}
```

```html
<!-- component.html -->
<shaqra-dga-ranged-datepicker
  label="Select Date Range"
  placeholder="DD/MM/YY - DD/MM/YY"
  [(value)]="dateRange"
  (rangeChange)="onRangeChange($event)">
</shaqra-dga-ranged-datepicker>
```

### File Uploader Component

```typescript
// component.ts
import { Component } from '@angular/core';
import { UploadedFile } from 'shaqra-dga-platformscode-angular';

@Component({
  selector: 'app-uploader-demo',
  templateUrl: './uploader-demo.component.html'
})
export class UploaderDemoComponent {
  uploadedFiles: UploadedFile[] = [];

  onFilesChange(files: UploadedFile[]) {
    this.uploadedFiles = files;
    console.log('Uploaded files:', files);
  }

  onFileError(error: string) {
    alert(error);
  }
}
```

```html
<!-- component.html -->
<shaqra-dga-file-uploader
  [maxFileSize]="5242880"
  [acceptedFormats]="['.jpg', '.jpeg', '.png', '.pdf', '.docx']"
  [numberOfAllowedFiles]="3"
  dragDropText="Drag and drop files here"
  browseButtonText="Browse Files"
  descriptionText="Maximum 5MB per file. Formats: JPG, PNG, PDF, DOCX"
  (filesChange)="onFilesChange($event)"
  (fileError)="onFileError($event)">
</shaqra-dga-file-uploader>
```

## 🎨 Complete Form Example

Here's a complete example combining multiple components:

```typescript
// registration-form.component.ts
import { Component } from '@angular/core';
import { DropdownOption, DateRange } from 'shaqra-dga-platformscode-angular';

@Component({
  selector: 'app-registration-form',
  templateUrl: './registration-form.component.html'
})
export class RegistrationFormComponent {
  // Form fields
  fullName: string = '';
  email: string = '';
  country: any = null;
  birthDate: Date | null = null;
  employmentDates: DateRange = { startDate: null, endDate: null };
  
  // Dropdown options
  countries: DropdownOption[] = [
    { value: 'sa', label: 'Saudi Arabia' },
    { value: 'ae', label: 'UAE' },
    { value: 'eg', label: 'Egypt' }
  ];

  onSubmit() {
    const formData = {
      fullName: this.fullName,
      email: this.email,
      country: this.country,
      birthDate: this.birthDate,
      employmentDates: this.employmentDates
    };
    console.log('Form submitted:', formData);
  }
}
```

```html
<!-- registration-form.component.html -->
<form (ngSubmit)="onSubmit()">
  <h2>Registration Form</h2>

  <shaqra-dga-text-input
    label="Full Name"
    placeholder="Enter your full name"
    [(value)]="fullName"
    [required]="true">
  </shaqra-dga-text-input>

  <shaqra-dga-text-input
    label="Email"
    placeholder="your.email@example.com"
    type="email"
    [(value)]="email"
    [required]="true">
  </shaqra-dga-text-input>

  <shaqra-dga-dropdown
    label="Country"
    placeholder="Select your country"
    [options]="countries"
    [(value)]="country"
    [required]="true">
  </shaqra-dga-dropdown>

  <shaqra-dga-single-datepicker
    label="Date of Birth"
    placeholder="DD/MM/YY"
    [(value)]="birthDate">
  </shaqra-dga-single-datepicker>

  <shaqra-dga-ranged-datepicker
    label="Employment Period"
    placeholder="DD/MM/YY - DD/MM/YY"
    [(value)]="employmentDates">
  </shaqra-dga-ranged-datepicker>

  <div class="form-actions">
    <shaqra-dga-button 
      variant="neutral" 
      type="button">
      Cancel
    </shaqra-dga-button>
    
    <shaqra-dga-button 
      variant="primary" 
      type="submit">
      Submit
    </shaqra-dga-button>
  </div>
</form>
```

## ⚙️ Component Properties Reference

### Button Component

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `variant` | `'primary' \| 'neutral' \| 'danger'` | `'primary'` | Button style variant |
| `size` | `'small' \| 'medium' \| 'large'` | `'large'` | Button size |
| `disabled` | `boolean` | `false` | Disable button |
| `loading` | `boolean` | `false` | Show loading state |
| `selected` | `boolean` | `false` | Mark as selected |
| `showIcon` | `boolean` | `true` | Show icon |
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | HTML button type |
| `(clicked)` | `EventEmitter<void>` | - | Click event emitter |

### Text Input Component

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `label` | `string` | `''` | Input label |
| `placeholder` | `string` | `''` | Placeholder text |
| `type` | `string` | `'text'` | Input type (text, email, password, etc.) |
| `disabled` | `boolean` | `false` | Disable input |
| `required` | `boolean` | `false` | Mark as required |
| `[(value)]` | `string` | `''` | Two-way binding for input value |
| `(valueChange)` | `EventEmitter<string>` | - | Value change event |

### Dropdown Component

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `label` | `string` | `''` | Dropdown label |
| `placeholder` | `string` | `'إختيار'` | Placeholder text |
| `options` | `DropdownOption[]` | `[]` | Array of options |
| `disabled` | `boolean` | `false` | Disable dropdown |
| `required` | `boolean` | `false` | Mark as required |
| `[(value)]` | `any` | `null` | Two-way binding for selected value |
| `(selectionChange)` | `EventEmitter<DropdownOption>` | - | Selection change event |

### Content Switcher Component

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `items` | `ContentSwitcherItem[]` | `[]` | Array of items |
| `variant` | `'primary' \| 'secondary'` | `'secondary'` | Style variant |
| `selectedId` | `string \| number \| null` | `null` | Currently selected item ID |
| `disabled` | `boolean` | `false` | Disable all items |
| `(selectionChange)` | `EventEmitter<ContentSwitcherItem>` | - | Selection change event |

### Single Date Picker Component

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `label` | `string` | `''` | Date picker label |
| `placeholder` | `string` | `'DD/MM/YY'` | Placeholder text |
| `disabled` | `boolean` | `false` | Disable picker |
| `readonly` | `boolean` | `false` | Make read-only |
| `required` | `boolean` | `false` | Mark as required |
| `minDate` | `Date \| null` | `null` | Minimum selectable date |
| `maxDate` | `Date \| null` | `null` | Maximum selectable date |
| `[(value)]` | `Date \| null` | `null` | Two-way binding for selected date |
| `(dateChange)` | `EventEmitter<Date \| null>` | - | Date change event |

### Ranged Date Picker Component

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `label` | `string` | `''` | Date picker label |
| `placeholder` | `string` | `'DD/MM/YY - DD/MM/YY'` | Placeholder text |
| `disabled` | `boolean` | `false` | Disable picker |
| `readonly` | `boolean` | `false` | Make read-only |
| `required` | `boolean` | `false` | Mark as required |
| `minDate` | `Date \| null` | `null` | Minimum selectable date |
| `maxDate` | `Date \| null` | `null` | Maximum selectable date |
| `[(value)]` | `DateRange` | `{startDate: null, endDate: null}` | Two-way binding for date range |
| `(rangeChange)` | `EventEmitter<DateRange>` | - | Range change event |

### File Uploader Component

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `disabled` | `boolean` | `false` | Disable uploader |
| `maxFileSize` | `number` | `2097152` (2MB) | Maximum file size in bytes |
| `acceptedFormats` | `string[]` | `['.jpg', '.jpeg', '.png', '.pdf']` | Accepted file formats |
| `numberOfAllowedFiles` | `number \| null` | `null` | Max number of files (null = unlimited) |
| `dragDropText` | `string` | `'Drag and drop files here to upload'` | Drag drop area text |
| `browseButtonText` | `string` | `'Browse Files'` | Browse button text |
| `descriptionText` | `string` | Default description | Helper text |
| `(filesChange)` | `EventEmitter<UploadedFile[]>` | - | Files change event |
| `(fileError)` | `EventEmitter<string>` | - | File error event |

## 🔧 Type Definitions

```typescript
// Dropdown types
export interface DropdownOption {
  value: any;
  label: string;
  disabled?: boolean;
}

// Content Switcher types
export interface ContentSwitcherItem {
  id: string | number;
  label: string;
  disabled?: boolean;
}

// Date Range types
export interface DateRange {
  startDate: Date | null;
  endDate: Date | null;
}

// File Upload types
export interface UploadedFile {
  id: string;
  name: string;
  size: number;
  type: string;
  file: File;
}
```

## 🛠️ Form Integration

All input components support Angular Forms (both Template-driven and Reactive Forms):

### Template-driven Forms

```html
<form #myForm="ngForm">
  <shaqra-dga-text-input
    name="username"
    [(ngModel)]="username"
    required>
  </shaqra-dga-text-input>
  
  <shaqra-dga-dropdown
    name="country"
    [(ngModel)]="selectedCountry"
    [options]="countries">
  </shaqra-dga-dropdown>
</form>
```

### Reactive Forms

```typescript
import { FormGroup, FormControl, Validators } from '@angular/forms';

this.myForm = new FormGroup({
  username: new FormControl('', Validators.required),
  country: new FormControl(null)
});
```

```html
<form [formGroup]="myForm">
  <shaqra-dga-text-input formControlName="username"></shaqra-dga-text-input>
  <shaqra-dga-dropdown formControlName="country" [options]="countries"></shaqra-dga-dropdown>
</form>
```

## 🌍 RTL Support

The library fully supports right-to-left (RTL) languages. Simply set the `dir` attribute on your container:

```html
<div dir="rtl">
  <shaqra-dga-text-input placeholder="أدخل النص هنا"></shaqra-dga-text-input>
  <shaqra-dga-button variant="primary">إرسال</shaqra-dga-button>
</div>
```

## 🔧 Troubleshooting

### Common Issues

**1. Components not rendering:**
```typescript
// Make sure you have CUSTOM_ELEMENTS_SCHEMA
@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA]  // This is required!
})
```

**2. TypeScript errors:**
```typescript
// Add to tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true
  }
}
```

**3. Two-way binding not working:**
```html
<!-- Make sure to use the correct syntax -->
<shaqra-dga-text-input [(value)]="myValue"></shaqra-dga-text-input>
<!-- NOT ngModel unless you're using forms -->
```

**4. Events not firing:**
```html
<!-- Use the correct event names -->
<shaqra-dga-button (clicked)="onClick()">Click</shaqra-dga-button>
<!-- NOT (click) -->
```

### Server-Side Rendering (SSR)

For Angular Universal/SSR support:

```typescript
import { isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID, Inject } from '@angular/core';

export class MyComponent {
  constructor(@Inject(PLATFORM_ID) private platformId: Object) {}

  ngOnInit() {
    if (isPlatformBrowser(this.platformId)) {
      // Components are available here
    }
  }
}
```

## 🤝 Contributing

We welcome contributions! To contribute:

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## 📝 License

This project is licensed under the ISC License.

## 🔗 Links

- [npm Package](https://www.npmjs.com/package/shaqra-dga-platformscode-angular)

## 📞 Support

For support and questions:

- 📧 Email: sulimanalbraim4@gmail.com

---

Made with ❤️ for the Angular community
