npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

shaqra-dga-platformscode-angular

v1.0.1

Published

A comprehensive Angular component library for building modern web applications with DGA Design System integration. Includes form controls, date pickers, file uploaders, and more.

Readme

Shaqra DGA PlatformsCode Angular Library

npm version License: 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:

npm install shaqra-dga-platformscode-angular @platformscode/[email protected]

Basic Setup

For Module-based Angular Apps

  1. Import the module in your app.module.ts:
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 { }
  1. Use components in your templates:
<!-- 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

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

// component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html'
})
export class DemoComponent {
  onButtonClick() {
    console.log('Button clicked!');
  }
}
<!-- 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

// component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-form',
  templateUrl: './form.component.html'
})
export class FormComponent {
  username: string = '';
  email: string = '';
  password: string = '';
}
<!-- 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

// 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);
  }
}
<!-- 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

// 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);
  }
}
<!-- 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

// 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);
  }
}
<!-- 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

// 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);
  }
}
<!-- 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

// 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);
  }
}
<!-- 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:

// 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);
  }
}
<!-- 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="[email protected]"
    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

// 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

<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

import { FormGroup, FormControl, Validators } from '@angular/forms';

this.myForm = new FormGroup({
  username: new FormControl('', Validators.required),
  country: new FormControl(null)
});
<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:

<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:

// Make sure you have CUSTOM_ELEMENTS_SCHEMA
@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA]  // This is required!
})

2. TypeScript errors:

// Add to tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

3. Two-way binding not working:

<!-- 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:

<!-- 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:

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

📞 Support

For support and questions:


Made with ❤️ for the Angular community