Angular Bootstrap component library providing comprehensive UI components for Angular applications
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Advanced form controls including datepickers, timepickers, typeahead, rating, and button controls for enhanced user input.
Bootstrap-styled date picker with comprehensive configuration options and localization support.
/**
* Bootstrap date picker directive for single date selection
*/
@Directive({
selector: '[bsDatepicker]'
})
class BsDatepickerDirective implements OnInit, OnDestroy {
/** Configuration options */
@Input() bsConfig: Partial<BsDatepickerConfig>;
/** Selected date value */
@Input() bsValue: Date;
/** Minimum selectable date */
@Input() minDate: Date;
/** Maximum selectable date */
@Input() maxDate: Date;
/** Custom CSS classes for specific dates */
@Input() dateCustomClasses: DatepickerDateCustomClasses[];
/** Days of week to disable (0-6, Sunday-Saturday) */
@Input() daysDisabled: number[];
/** Specific dates to disable */
@Input() datesDisabled: Date[];
/** Datepicker placement */
@Input() placement: 'top' | 'bottom' | 'left' | 'right' = 'bottom';
/** Event triggers */
@Input() triggers: string = 'click';
/** Container for datepicker */
@Input() container: string = 'body';
/** Disable the datepicker */
@Input() isDisabled: boolean = false;
/** Event emitted when datepicker is shown */
@Output() onShown: EventEmitter<BsDatepickerDirective>;
/** Event emitted when datepicker is hidden */
@Output() onHidden: EventEmitter<BsDatepickerDirective>;
/** Event emitted when date value changes */
@Output() bsValueChange: EventEmitter<Date>;
/** Show the datepicker */
show(): void;
/** Hide the datepicker */
hide(): void;
/** Toggle datepicker visibility */
toggle(): void;
/** Set date value */
setConfig(): void;
}
/**
* Inline datepicker directive (always visible)
*/
@Directive({
selector: '[bsDatepickerInline]'
})
class BsDatepickerInlineDirective extends BsDatepickerDirective {}
/**
* Date range picker directive for selecting date ranges
*/
@Directive({
selector: '[bsDaterangepicker]'
})
class BsDaterangepickerDirective implements OnInit, OnDestroy {
/** Configuration options */
@Input() bsConfig: Partial<BsDaterangepickerConfig>;
/** Selected date range */
@Input() bsValue: Date[];
/** Minimum selectable date */
@Input() minDate: Date;
/** Maximum selectable date */
@Input() maxDate: Date;
/** Custom CSS classes for specific dates */
@Input() dateCustomClasses: DatepickerDateCustomClasses[];
/** Days to disable */
@Input() daysDisabled: number[];
/** Specific dates to disable */
@Input() datesDisabled: Date[];
/** Placement relative to trigger */
@Input() placement: 'top' | 'bottom' | 'left' | 'right' = 'bottom';
/** Event triggers */
@Input() triggers: string = 'click';
/** Container for datepicker */
@Input() container: string = 'body';
/** Disable the datepicker */
@Input() isDisabled: boolean = false;
/** Event emitted when shown */
@Output() onShown: EventEmitter<BsDaterangepickerDirective>;
/** Event emitted when hidden */
@Output() onHidden: EventEmitter<BsDaterangepickerDirective>;
/** Event emitted when date range changes */
@Output() bsValueChange: EventEmitter<Date[]>;
}
/**
* Configuration interface for datepicker
*/
interface BsDatepickerConfig {
/** Container CSS class */
containerClass: string;
/** Custom CSS class */
customClass: string;
/** Date input format */
dateInputFormat: string;
/** Use UTC dates */
useUtc: boolean;
/** Return focus to trigger after selection */
returnFocusToInput: boolean;
/** Show week numbers */
showWeekNumbers: boolean;
/** First day of week (0-6) */
startingDayOfWeek: number;
/** Adaptive position */
adaptivePosition: boolean;
/** Show today button */
showTodayButton: boolean;
/** Show clear button */
showClearButton: boolean;
/** Clear button label */
clearButtonLabel: string;
/** Today button label */
todayButtonLabel: string;
/** Clear position */
clearPosition: string;
/** Today position */
todayPosition: string;
/** Range separator for date ranges */
rangeSeparator: string;
/** Select week */
selectWeek: boolean;
/** Select from other month */
selectFromOtherMonth: boolean;
/** Display one month */
displayOneMonthRange: boolean;
/** Display months */
displayMonths: number;
}
/**
* Date custom classes interface
*/
interface DatepickerDateCustomClasses {
/** Target date */
date: Date;
/** CSS classes to apply */
classes: string[];
}
/**
* View modes for datepicker
*/
type BsDatepickerViewMode = 'day' | 'month' | 'year';
/**
* Localization service for datepicker
*/
@Injectable()
class BsLocaleService {
/** Current locale */
currentLocale: string;
/** Use specified locale */
use(locale: string): void;
/** Get current locale data */
getCurrentLocale(): string;
/** Get locale data */
getLocaleData(locale: string): any;
}
/**
* Angular module for datepicker functionality
*/
@NgModule({
declarations: [
BsDatepickerDirective,
BsDatepickerInlineDirective,
BsDaterangepickerDirective,
BsDaterangepickerInlineDirective,
BsDatepickerInputDirective,
BsDaterangepickerInputDirective
],
exports: [
BsDatepickerDirective,
BsDatepickerInlineDirective,
BsDaterangepickerDirective,
BsDaterangepickerInlineDirective,
BsDatepickerInputDirective,
BsDaterangepickerInputDirective
],
providers: [BsLocaleService]
})
class BsDatepickerModule {}Usage Example:
import { BsDatepickerModule, BsDatepickerConfig, BsLocaleService } from 'ngx-bootstrap/datepicker';
import { defineLocale } from 'ngx-bootstrap/chronos';
import { esLocale } from 'ngx-bootstrap/locale';
@Component({
template: `
<!-- Single date picker -->
<input
type="text"
class="form-control"
bsDatepicker
[bsValue]="selectedDate"
[bsConfig]="datePickerConfig"
(bsValueChange)="onDateChange($event)"
placeholder="Select date">
<!-- Date range picker -->
<input
type="text"
class="form-control"
bsDaterangepicker
[bsValue]="dateRange"
[minDate]="minDate"
[maxDate]="maxDate"
(bsValueChange)="onRangeChange($event)"
placeholder="Select date range">
<!-- Inline datepicker -->
<div
bsDatepickerInline
[bsValue]="selectedDate"
(bsValueChange)="onDateChange($event)">
</div>
`,
imports: [BsDatepickerModule]
})
export class MyComponent {
selectedDate = new Date();
dateRange: Date[] = [];
minDate = new Date();
maxDate = new Date();
datePickerConfig: Partial<BsDatepickerConfig> = {
showWeekNumbers: true,
dateInputFormat: 'YYYY-MM-DD',
containerClass: 'theme-dark-blue'
};
constructor(private localeService: BsLocaleService) {
// Set locale
defineLocale('es', esLocale);
this.localeService.use('es');
// Set date constraints
this.maxDate.setDate(this.maxDate.getDate() + 7);
}
onDateChange(date: Date) {
this.selectedDate = date;
}
onRangeChange(range: Date[]) {
this.dateRange = range;
}
}Time selection component with configurable step intervals and 12/24 hour formats.
/**
* Time selection component
*/
@Component({
selector: 'timepicker'
})
class TimepickerComponent implements ControlValueAccessor, OnInit {
/** Hours step interval */
@Input() hourStep: number = 1;
/** Minutes step interval */
@Input() minuteStep: number = 5;
/** Seconds step interval */
@Input() secondsStep: number = 10;
/** Make inputs readonly */
@Input() readonlyInput: boolean = false;
/** Disable the component */
@Input() disabled: boolean = false;
/** Enable mousewheel support */
@Input() mousewheel: boolean = true;
/** Enable arrow key support */
@Input() arrowkeys: boolean = true;
/** Show spinner buttons */
@Input() showSpinners: boolean = true;
/** Show seconds input */
@Input() showSeconds: boolean = false;
/** Show minutes input */
@Input() showMinutes: boolean = true;
/** Show AM/PM selector */
@Input() showMeridian: boolean = true;
/** AM/PM labels */
@Input() meridians: string[] = ['AM', 'PM'];
/** Minimum time */
@Input() min: Date;
/** Maximum time */
@Input() max: Date;
/** Placeholder for hours */
@Input() hoursPlaceholder: string = 'HH';
/** Placeholder for minutes */
@Input() minutesPlaceholder: string = 'MM';
/** Placeholder for seconds */
@Input() secondsPlaceholder: string = 'SS';
/** Allow empty time values */
@Input() allowEmptyTime: boolean = false;
/** Increment hours */
incrementHours(): void;
/** Decrement hours */
decrementHours(): void;
/** Increment minutes */
incrementMinutes(): void;
/** Decrement minutes */
decrementMinutes(): void;
/** Increment seconds */
incrementSeconds(): void;
/** Decrement seconds */
decrementSeconds(): void;
/** Toggle meridian (AM/PM) */
toggleMeridian(): void;
}
/**
* Global configuration for timepicker
*/
@Injectable()
class TimepickerConfig {
/** Default hours step */
hourStep: number = 1;
/** Default minutes step */
minuteStep: number = 5;
/** Default seconds step */
secondsStep: number = 10;
/** Default meridian display */
showMeridian: boolean = true;
/** Default meridian labels */
meridians: string[] = ['AM', 'PM'];
/** Default readonly state */
readonlyInput: boolean = false;
/** Default disabled state */
disabled: boolean = false;
/** Default mousewheel support */
mousewheel: boolean = true;
/** Default arrow key support */
arrowkeys: boolean = true;
/** Default spinner display */
showSpinners: boolean = true;
/** Default seconds display */
showSeconds: boolean = false;
/** Default minutes display */
showMinutes: boolean = true;
/** Default empty time handling */
allowEmptyTime: boolean = false;
/** Default minimum time */
min?: Date;
/** Default maximum time */
max?: Date;
/** Default hours placeholder */
hoursPlaceholder: string = 'HH';
/** Default minutes placeholder */
minutesPlaceholder: string = 'MM';
/** Default seconds placeholder */
secondsPlaceholder: string = 'SS';
/** Default hours aria label */
ariaLabelHours: string = 'hours';
/** Default minutes aria label */
ariaLabelMinutes: string = 'minutes';
/** Default seconds aria label */
ariaLabelSeconds: string = 'seconds';
}
/**
* Angular module for timepicker functionality
*/
@NgModule({
declarations: [TimepickerComponent],
exports: [TimepickerComponent]
})
class TimepickerModule {}Usage Example:
import { TimepickerModule, TimepickerConfig } from 'ngx-bootstrap/timepicker';
@Component({
template: `
<timepicker
[(ngModel)]="selectedTime"
[hourStep]="1"
[minuteStep]="15"
[showMeridian]="true"
[showSeconds]="false"
[readonlyInput]="false"
[disabled]="isDisabled">
</timepicker>
<timepicker
[(ngModel)]="time24"
[showMeridian]="false"
[showSeconds]="true"
[min]="minTime"
[max]="maxTime">
</timepicker>
`,
imports: [TimepickerModule]
})
export class MyComponent {
selectedTime = new Date();
time24 = new Date();
isDisabled = false;
minTime = new Date();
maxTime = new Date();
constructor(timepickerConfig: TimepickerConfig) {
// Global configuration
timepickerConfig.showMeridian = false;
timepickerConfig.showSeconds = true;
// Set time constraints
this.minTime.setHours(9, 0, 0);
this.maxTime.setHours(17, 30, 0);
}
}Auto-complete functionality with flexible data sources and customizable matching.
/**
* Typeahead directive for auto-complete functionality
*/
@Directive({
selector: '[typeahead]'
})
class TypeaheadDirective implements OnInit, OnDestroy {
/** Data source for suggestions */
@Input() typeahead: any;
/** Minimum characters to trigger search */
@Input() typeaheadMinLength: number = 1;
/** Wait time before triggering search */
@Input() typeaheadWaitMs: number = 0;
/** Maximum number of options to display */
@Input() typeaheadOptionsLimit: number = 20;
/** Custom option template */
@Input() typeaheadOptionField: string;
/** Async loading indicator */
@Input() typeaheadAsync: boolean;
/** Latinize characters for matching */
@Input() typeaheadLatinize: boolean = true;
/** Single words matching */
@Input() typeaheadSingleWords: boolean = true;
/** Word delimiters */
@Input() typeaheadWordDelimiters: string = ' ';
/** Phrase delimiters */
@Input() typeaheadPhraseDelimiters: string = '\'"';
/** Loading text */
@Input() typeaheadLoadingText: string = 'Loading...';
/** No results text */
@Input() typeaheadNoResultsText: string = 'No Results Found';
/** Hide results on blur */
@Input() typeaheadHideResultsOnBlur: boolean = true;
/** Cancel request on focus lost */
@Input() typeaheadCancelRequestOnFocusLost: boolean = false;
/** Select first item */
@Input() typeaheadSelectFirstItem: boolean = true;
/** Scroll to active option */
@Input() typeaheadScrollable: boolean = false;
/** Scroll height */
@Input() typeaheadOptionsInScrollableView: number = 5;
/** Container for dropdown */
@Input() container: string;
/** Dropdown up */
@Input() dropup: boolean = false;
/** Event emitted when loading starts */
@Output() typeaheadLoading: EventEmitter<boolean> = new EventEmitter();
/** Event emitted when no results found */
@Output() typeaheadNoResults: EventEmitter<boolean> = new EventEmitter();
/** Event emitted when option is selected */
@Output() typeaheadOnSelect: EventEmitter<TypeaheadMatch> = new EventEmitter();
/** Event emitted when preview changes */
@Output() typeaheadOnPreview: EventEmitter<TypeaheadMatch> = new EventEmitter();
/** Event emitted when blur occurs */
@Output() typeaheadOnBlur: EventEmitter<any> = new EventEmitter();
/** Change active option */
changeModel(match: TypeaheadMatch): void;
/** Get active option */
getActive(): TypeaheadMatch;
/** Select active option */
selectActiveMatch(): void;
/** Select match */
selectMatch(value: TypeaheadMatch): void;
/** Show matches */
show(): void;
/** Hide matches */
hide(): void;
}
/**
* Typeahead match result
*/
class TypeaheadMatch {
constructor(
public item: any,
public value?: string,
public header?: boolean
) {}
/** Check if option is header */
isHeader(): boolean;
/** String representation */
toString(): string;
}
/**
* Typeahead configuration options
*/
class TypeaheadOptions {
/** Placement of dropdown */
placement: string;
/** Animation enabled */
animation: boolean;
/** Typeahead container */
typeaheadRef: any;
}
/**
* Global configuration for typeahead
*/
@Injectable()
class TypeaheadConfig {
/** Default hide results on blur */
hideResultsOnBlur: boolean = true;
/** Default cancel request on focus lost */
cancelRequestOnFocusLost: boolean = false;
/** Default select first item */
selectFirstItem: boolean = true;
/** Default minimum length */
minLength: number = 1;
/** Default wait time */
waitMs: number = 0;
}
/**
* Utility functions for typeahead
*/
interface TypeaheadUtils {
/** Escape regex special characters */
escapeRegexp(text: string): string;
/** Get value from nested object property */
getValueFromObject(object: any, path: string): string;
/** Tokenize text for matching */
tokenize(text: string, wordRegexDelimiters?: string, phraseRegexDelimiters?: string): string[];
/** Convert text to latin characters */
latinize(text: string): string;
}
/** Character mapping for latinization */
declare const latinMap: { [key: string]: string };
/**
* Template context interfaces
*/
interface TypeaheadOptionItemContext {
/** Match object */
$implicit: TypeaheadMatch;
/** Match index */
index: number;
}
interface TypeaheadOptionListContext {
/** All matches */
$implicit: TypeaheadMatch[];
/** Query string */
query: string;
}
/**
* Angular module for typeahead functionality
*/
@NgModule({
declarations: [
TypeaheadDirective,
TypeaheadContainerComponent
],
exports: [TypeaheadDirective]
})
class TypeaheadModule {}Usage Example:
import { TypeaheadModule } from 'ngx-bootstrap/typeahead';
import { Observable, of } from 'rxjs';
import { map, mergeMap } from 'rxjs/operators';
@Component({
template: `
<!-- Static data source -->
<input
type="text"
class="form-control"
[(ngModel)]="selectedState"
[typeahead]="states"
placeholder="Type to search states">
<!-- Async data source -->
<input
type="text"
class="form-control"
[(ngModel)]="selectedUser"
[typeahead]="asyncUsers"
typeaheadOptionField="name"
[typeaheadMinLength]="2"
[typeaheadWaitMs]="300"
(typeaheadOnSelect)="onUserSelect($event)"
placeholder="Search users">
<!-- Custom template -->
<input
type="text"
class="form-control"
[(ngModel)]="selectedProduct"
[typeahead]="products"
typeaheadOptionField="name"
[typeaheadItemTemplate]="customTemplate"
placeholder="Search products">
<ng-template #customTemplate let-model="item" let-index="index">
<div>
<strong>{{model.name}}</strong> - ${{model.price}}
</div>
</ng-template>
`,
imports: [TypeaheadModule]
})
export class MyComponent {
selectedState: string;
selectedUser: string;
selectedProduct: string;
states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California'];
products = [
{ name: 'Laptop', price: 999 },
{ name: 'Mouse', price: 25 },
{ name: 'Keyboard', price: 75 }
];
asyncUsers = new Observable((observer: any) => {
// Simulate API call
observer.next([
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
]);
});
onUserSelect(event: any) {
console.log('Selected user:', event.item);
}
}Star rating component with configurable icons and half-star support.
/**
* Star rating component
*/
@Component({
selector: 'rating'
})
class RatingComponent implements ControlValueAccessor, OnInit {
/** Maximum rating value */
@Input() max: number = 5;
/** Current rating value */
@Input() rate: number = 0;
/** Read-only mode */
@Input() readonly: boolean = false;
/** Custom titles for rating values */
@Input() titles: string[] = [];
/** Enable/disable rating */
@Input() disabled: boolean = false;
/** Custom template for rating display */
@Input() customTemplate: TemplateRef<any>;
/** Event emitted when rating changes */
@Output() onHover: EventEmitter<number> = new EventEmitter();
/** Event emitted when mouse leaves */
@Output() onLeave: EventEmitter<number> = new EventEmitter();
/** Rating range array */
range: number[] = [];
/** Current hover value */
preValue: number;
/** Enter rating item */
enter(value: number): void;
/** Reset to original value */
reset(): void;
/** Select rating value */
rate(value: number): void;
}
/**
* Global configuration for rating
*/
@Injectable()
class RatingConfig {
/** Default maximum rating */
max: number = 5;
/** Default readonly state */
readonly: boolean = false;
/** Default disabled state */
disabled: boolean = false;
}
/**
* Angular module for rating functionality
*/
@NgModule({
declarations: [RatingComponent],
exports: [RatingComponent]
})
class RatingModule {}Usage Example:
import { RatingModule } from 'ngx-bootstrap/rating';
@Component({
template: `
<!-- Basic rating -->
<rating
[(ngModel)]="currentRate"
[max]="maxRating"
[readonly]="false"
(onHover)="onRatingHover($event)"
(onLeave)="onRatingLeave($event)">
</rating>
<!-- Custom titles -->
<rating
[(ngModel)]="productRating"
[titles]="ratingTitles"
[disabled]="isDisabled">
</rating>
<!-- Readonly display -->
<rating
[ngModel]="averageRating"
[readonly]="true"
[max]="5">
</rating>
`,
imports: [RatingModule]
})
export class MyComponent {
currentRate = 3;
maxRating = 10;
productRating = 4;
averageRating = 4.5;
isDisabled = false;
ratingTitles = ['Poor', 'Fair', 'Good', 'Very Good', 'Excellent'];
onRatingHover(rating: number) {
console.log('Hovering over rating:', rating);
}
onRatingLeave(rating: number) {
console.log('Left rating:', rating);
}
}Button directives for checkbox and radio button behavior.
/**
* Directive for checkbox-like button behavior
*/
@Directive({
selector: '[btnCheckbox]'
})
class ButtonCheckboxDirective implements ControlValueAccessor, OnInit {
/** Button active state */
@Input() btnCheckbox: boolean;
/** Uncheckable button */
@Input() uncheckable: boolean = true;
/** True value for checkbox */
@Input() trueValue: any = true;
/** False value for checkbox */
@Input() falseValue: any = false;
/** Toggle button state */
toggle(): void;
}
/**
* Directive for radio button behavior
*/
@Directive({
selector: '[btnRadio]'
})
class ButtonRadioDirective implements ControlValueAccessor, OnInit {
/** Radio button value */
@Input() btnRadio: any;
/** Uncheckable radio */
@Input() uncheckable: boolean = false;
/** Radio group value */
@Input() value: any;
/** Set button state */
onClick(): void;
}
/**
* Group directive for radio buttons
*/
@Directive({
selector: '[btnRadioGroup]'
})
class ButtonRadioGroupDirective implements ControlValueAccessor {
/** Radio group value */
value: any;
/** Write value */
writeValue(value: any): void;
}
/**
* Angular module for button controls
*/
@NgModule({
declarations: [
ButtonCheckboxDirective,
ButtonRadioDirective,
ButtonRadioGroupDirective
],
exports: [
ButtonCheckboxDirective,
ButtonRadioDirective,
ButtonRadioGroupDirective
]
})
class ButtonsModule {}Usage Example:
import { ButtonsModule } from 'ngx-bootstrap/buttons';
@Component({
template: `
<!-- Checkbox buttons -->
<div class="btn-group" role="group">
<button
type="button"
class="btn btn-primary"
[(ngModel)]="checkboxModel.left"
btnCheckbox>
Left
</button>
<button
type="button"
class="btn btn-primary"
[(ngModel)]="checkboxModel.right"
btnCheckbox>
Right
</button>
</div>
<!-- Radio buttons -->
<div class="btn-group" role="group" [(ngModel)]="radioModel" btnRadioGroup>
<button
type="button"
class="btn btn-success"
btnRadio="Left">
Left
</button>
<button
type="button"
class="btn btn-success"
btnRadio="Middle">
Middle
</button>
<button
type="button"
class="btn btn-success"
btnRadio="Right">
Right
</button>
</div>
`,
imports: [ButtonsModule]
})
export class MyComponent {
checkboxModel = { left: false, right: false };
radioModel = 'Middle';
}