Package Exports
- sgh-select-lib
- sgh-select-lib/package.json
Readme
SGH Select Library
A comprehensive, feature-rich Angular select component library with advanced search, multi-select capabilities, and Bootstrap styling support.
✨ Features
- 🔍 Advanced Search - Built-in search/filter with debounced input
- 🎯 Single & Multiple Selection - Configurable selection modes
- 🎨 Bootstrap Integration - Full Bootstrap 5+ styling with CSS custom properties
- 🔧 Flexible Data Binding - Support for various data formats and custom property mapping
- 📱 Responsive Design - Mobile-friendly with Bootstrap responsive utilities
- ♿ Accessibility - WCAG compliant with ARIA support and keyboard navigation
- 🚀 Performance - Optimized rendering with virtual scrolling support
- 🎭 Customizable - Template slots for custom option rendering
- 🌙 Dark Theme Support - Bootstrap dark mode compatible
- 📦 Tree-shakable - Optimized bundle size with no Material dependencies
📦 Installation
npm install sgh-select-libPeer Dependencies
Make sure you have the following peer dependencies installed:
npm install @angular/core @angular/common @angular/forms bootstrap rxjsBootstrap Setup
Add Bootstrap CSS to your project. You can either:
Option 1: Install Bootstrap via npm
npm install bootstrapThen add to your angular.json styles array:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.scss"
]Option 2: Use Bootstrap CDN
Add to your src/index.html:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">🚀 Quick Start
1. Import the Module
import { SghSelectLibModule } from 'sgh-select-lib';
@NgModule({
imports: [
SghSelectLibModule,
// ... other imports
],
// ...
})
export class AppModule { }2. Basic Usage
<!-- Advanced select with Bootstrap styling -->
<sgh-select
[options]="['Option 1', 'Option 2', 'Option 3']"
placeholder="Choose an option"
(selectionChange)="onSelectionChange($event)">
</sgh-select>
<!-- Simple native select (for basic use cases) -->
<sgh-select-simple
[options]="['Option 1', 'Option 2', 'Option 3']"
placeholder="Choose an option"
(selectionChange)="onSelectionChange($event)">
</sgh-select-simple>3. Advanced Usage
<!-- Object array with custom mapping -->
<sgh-select
[options]="workQueueList"
[multiple]="false"
[searchable]="true"
labelKey="workQueueName"
valueKey="workQueueId"
placeholder="Select work queue"
searchPlaceholder="Search queues..."
[clearable]="true"
(selectionChange)="onWorkQueueChange($event)"
(searchChange)="onSearchChange($event)">
</sgh-select>📚 API Reference
Component Properties
Input Properties
| Property | Type | Default | Description |
|---|---|---|---|
options |
any[] |
[] |
Array of options to display |
multiple |
boolean |
false |
Enable multiple selection mode |
searchable |
boolean |
true |
Enable search/filter functionality |
labelKey |
string |
'label' |
Property name for display text |
valueKey |
string |
'value' |
Property name for option value |
disabledKey |
string |
'disabled' |
Property name for disabled state |
groupKey |
string |
undefined |
Property name for option grouping |
placeholder |
string |
'Select...' |
Placeholder text |
searchPlaceholder |
string |
'Search...' |
Search input placeholder |
disabled |
boolean |
false |
Disable the component |
required |
boolean |
false |
Mark as required field |
clearable |
boolean |
true |
Show clear button |
maxSelections |
number |
undefined |
Maximum selections (multiple mode) |
noOptionsText |
string |
'No options found' |
Text when no options available |
loadingText |
string |
'Loading...' |
Loading state text |
loading |
boolean |
false |
Show loading state |
compareWith |
function |
undefined |
Custom comparison function |
Output Events
| Event | Type | Description |
|---|---|---|
selectionChange |
SelectChangeEvent |
Fired when selection changes |
searchChange |
SelectSearchEvent |
Fired when search term changes |
opened |
void |
Fired when dropdown opens |
closed |
void |
Fired when dropdown closes |
focus |
void |
Fired when component receives focus |
blur |
void |
Fired when component loses focus |
Data Formats
The component supports various data formats:
Simple Arrays
const options = ['Apple', 'Banana', 'Orange'];Object Arrays
const options = [
{ id: 1, name: 'Apple', category: 'Fruit' },
{ id: 2, name: 'Banana', category: 'Fruit' },
{ id: 3, name: 'Carrot', category: 'Vegetable' }
];Complex Nested Objects
const options = [
{
workQueueId: "1",
workQueueName: "Processing Queue",
assignedVisits: 5,
details: { priority: 'high', department: 'IT' }
}
];💡 Usage Examples
Single Select with Search
<sgh-select
[options]="countries"
labelKey="name"
valueKey="code"
placeholder="Select country"
[searchable]="true"
(selectionChange)="onCountrySelect($event)">
</sgh-select>export class ExampleComponent {
countries = [
{ code: 'US', name: 'United States' },
{ code: 'CA', name: 'Canada' },
{ code: 'UK', name: 'United Kingdom' }
];
onCountrySelect(event: SelectChangeEvent) {
console.log('Selected:', event.value);
console.log('Option data:', event.option);
}
}Multiple Select with Max Selections
<sgh-select
[options]="skills"
[multiple]="true"
[maxSelections]="3"
labelKey="name"
valueKey="id"
placeholder="Select up to 3 skills"
(selectionChange)="onSkillsChange($event)">
</sgh-select>Grouped Options
<sgh-select
[options]="employees"
labelKey="name"
valueKey="id"
groupKey="department"
placeholder="Select employee">
</sgh-select>employees = [
{ id: 1, name: 'John Doe', department: 'Engineering' },
{ id: 2, name: 'Jane Smith', department: 'Engineering' },
{ id: 3, name: 'Bob Wilson', department: 'Marketing' }
];Custom Templates
<sgh-select [options]="users" labelKey="name" valueKey="id">
<!-- Custom option template -->
<ng-template #optionTemplate let-option let-data="data">
<div class="custom-option">
<img [src]="data.avatar" alt="Avatar" class="avatar">
<div class="user-info">
<div class="name">{{ option.label }}</div>
<div class="email">{{ data.email }}</div>
</div>
</div>
</ng-template>
<!-- Custom selected value template -->
<ng-template #selectedTemplate let-options>
<span>{{ options.length }} users selected</span>
</ng-template>
</sgh-select>Reactive Forms Integration
<form [formGroup]="myForm">
<sgh-select
formControlName="selectedOption"
[options]="options"
labelKey="label"
valueKey="value"
placeholder="Select option">
</sgh-select>
</form>export class FormComponent implements OnInit {
myForm: FormGroup;
ngOnInit() {
this.myForm = this.fb.group({
selectedOption: ['', Validators.required]
});
}
}Loading State with Async Data
<sgh-select
[options]="options$ | async"
[loading]="loading"
loadingText="Fetching options..."
placeholder="Select option">
</sgh-select>export class AsyncComponent implements OnInit {
options$: Observable<any[]>;
loading = false;
ngOnInit() {
this.loading = true;
this.options$ = this.service.getOptions().pipe(
finalize(() => this.loading = false)
);
}
}🎨 Styling and Theming
CSS Custom Properties
The component uses CSS custom properties for easy theming with Bootstrap-compatible values:
:root {
/* Primary Colors (Bootstrap-compatible) */
--sgh-select-primary-color: #0d6efd;
--sgh-select-secondary-color: #6c757d;
--sgh-select-success-color: #198754;
--sgh-select-danger-color: #dc3545;
/* Background Colors */
--sgh-select-bg-color: #ffffff;
--sgh-select-hover-color: #e9ecef;
/* Text Colors */
--sgh-select-text-color: #212529;
--sgh-select-text-muted: #6c757d;
/* Border and Spacing */
--sgh-select-border-color: #ced4da;
--sgh-select-border-radius: 0.375rem;
--sgh-select-padding-x: 0.75rem;
--sgh-select-padding-y: 0.375rem;
}Bootstrap Dark Mode Support
The component automatically supports Bootstrap's dark mode:
<html data-bs-theme="dark">
<body>
<sgh-select [options]="options"></sgh-select>
</body>
</html>Custom Bootstrap Themes
// Custom Bootstrap theme
:root {
--sgh-select-primary-color: #e91e63;
--sgh-select-border-radius: 0.5rem;
}
// Size variants
.sgh-select-lg {
--sgh-select-font-size: 1.25rem;
--sgh-select-padding-y: 0.5rem;
--sgh-select-padding-x: 1rem;
}
.sgh-select-sm {
--sgh-select-font-size: 0.875rem;
--sgh-select-padding-y: 0.25rem;
--sgh-select-padding-x: 0.5rem;
}Custom Styling with Bootstrap Classes
<!-- Apply custom Bootstrap classes -->
<div class="my-custom-select">
<sgh-select
[options]="options"
class="sgh-select-primary">
</sgh-select>
</div>.my-custom-select {
.sgh-select-trigger {
@extend .btn-outline-success;
}
.sgh-dropdown-menu {
@extend .shadow-lg;
}
}🔧 Service Utilities
The library includes a service with helpful utilities:
import { SghSelectLibService } from 'sgh-select-lib';
export class MyComponent {
constructor(private selectService: SghSelectLibService) {}
ngOnInit() {
// Transform data to select options
const options = this.selectService.transformToSelectOptions(
this.rawData,
'displayName',
'id'
);
// Filter options
const filtered = this.selectService.filterOptions(
options,
'search term',
['description', 'category']
);
// Sort options
const sorted = this.selectService.sortOptions(options, 'label', 'asc');
}
}♿ Accessibility
The component follows WCAG guidelines and includes:
- Full keyboard navigation support
- Screen reader compatibility
- ARIA labels and descriptions
- Focus management
- High contrast mode support
Keyboard Shortcuts
| Key | Action |
|---|---|
Space/Enter |
Open dropdown |
Arrow Up/Down |
Navigate options |
Escape |
Close dropdown |
Tab |
Move focus |
Home/End |
First/last option |
🌐 Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)
📝 Development
Building the Library
ng build sgh-select-libRunning Tests
ng test sgh-select-libPublishing
cd dist/sgh-select-lib
npm publish🤝 Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🏷️ Changelog
v0.0.3
- BREAKING CHANGE: Migrated from Angular Material to Bootstrap 5+
- Removed all Material Design dependencies
- Added Bootstrap 5+ styling and theming support
- Improved CSS custom properties system
- Enhanced accessibility with Bootstrap ARIA patterns
- Maintained all existing functionality with Bootstrap UI
- Added Bootstrap dark mode compatibility
- Reduced bundle size by removing Material dependencies
v0.0.2
- Previous Material Design version
- Single and multiple selection support
- Advanced search functionality
- Material Design integration
- Accessibility features
- Custom templates
- Dark theme support
🔄 Migration from Material Design (v0.0.2 to v0.0.3)
If you're upgrading from the Material Design version, please note:
Required Changes:
Remove Angular Material dependencies:
npm uninstall @angular/material @angular/cdkInstall Bootstrap:
npm install bootstrap
Update styles: Replace Material theme with Bootstrap CSS (see Bootstrap Setup section above)
What's Changed:
- UI now uses Bootstrap styling instead of Material Design
- All functionality remains the same
- CSS custom properties have been updated with Bootstrap-compatible values
- Icons now use Font Awesome instead of Material Icons
What's Not Changed:
- All component APIs remain identical
- Event handlers work the same way
- Template slots and custom templates work the same way
- All input/output properties are unchanged
📞 Support
For issues and questions:
Made with ❤️ by SGH Development Team