@progress/kendo-angular-indicators
Version:
Kendo UI Indicators for Angular
685 lines (669 loc) • 25.9 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import * as i0 from '@angular/core';
import { Component, HostBinding, Input, isDevMode, ChangeDetectionStrategy, NgModule } from '@angular/core';
import * as i1 from '@progress/kendo-angular-l10n';
import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
import { validatePackage } from '@progress/kendo-licensing';
import { NgFor } from '@angular/common';
/**
* Represents the Kendo UI BadgeContainer component for Angular.
* Groups and aligns one or more Badge components within a parent element.
*
* @example
* ```html
* <kendo-badge-container>
* <kendo-badge>new</kendo-badge>
* </kendo-badge-container>
* ```
*
* @remarks
* Supported children components are: {@link BadgeComponent}.
*/
class BadgeContainerComponent {
localizationService;
hostClass = true;
/**
* @hidden
*/
direction;
dynamicRTLSubscription;
rtl = false;
constructor(localizationService) {
this.localizationService = localizationService;
this.dynamicRTLSubscription = this.localizationService.changes.subscribe(({ rtl }) => {
this.rtl = rtl;
this.direction = this.rtl ? 'rtl' : 'ltr';
});
}
ngOnDestroy() {
if (this.dynamicRTLSubscription) {
this.dynamicRTLSubscription.unsubscribe();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BadgeContainerComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BadgeContainerComponent, isStandalone: true, selector: "kendo-badge-container", host: { properties: { "class.k-badge-container": "this.hostClass", "attr.dir": "this.direction" } }, providers: [
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.badge.component'
}
], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BadgeContainerComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-badge-container',
providers: [
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.badge.component'
}
],
template: `<ng-content></ng-content>`,
standalone: true
}]
}], ctorParameters: function () { return [{ type: i1.LocalizationService }]; }, propDecorators: { hostClass: [{
type: HostBinding,
args: ['class.k-badge-container']
}], direction: [{
type: HostBinding,
args: ['attr.dir']
}] } });
/**
* @hidden
*/
const packageMetadata = {
name: '@progress/kendo-angular-indicators',
productName: 'Kendo UI for Angular',
productCode: 'KENDOUIANGULAR',
productCodes: ['KENDOUIANGULAR'],
publishDate: 1751463004,
version: '19.2.0',
licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
};
const SIZE_CLASSES$1 = {
'small': 'k-badge-sm',
'medium': 'k-badge-md',
'large': 'k-badge-lg'
};
const ROUNDED_CLASSES = {
'small': 'k-rounded-sm',
'medium': 'k-rounded-md',
'large': 'k-rounded-lg',
'full': 'k-rounded-full'
};
/**
* Represents the [Kendo UI Badge component for Angular]({% slug overview_badge %}).
* Displays additional information or status related to an element, such as notifications or counts.
*
* Provides configuration options for alignment, size, fill, theme color, roundness, position, and cutout border.
*
* @example
* ```html
* <kendo-badge [size]="'large'" [themeColor]="'success'">99+</kendo-badge>
* ```
*/
class BadgeComponent {
element;
renderer;
localizationService;
hostClass = true;
get cutoutBorderClass() {
return this.cutoutBorder;
}
/**
* @hidden
*/
direction;
/**
* Specifies the alignment of the Badge ([see example]({% slug alignandposition_badge %}#toc-alignment)).
*
* @default "{ vertical: 'top', horizontal: 'end' }"
*/
get align() {
return this.badgeAlign;
}
set align(align) {
this.badgeAlign = Object.assign(this.badgeAlign, align);
}
/**
* Specifies the size of the Badge ([see example]({% slug appearance_badge %}#toc-size)).
*
* @default medium
*/
size = 'medium';
/**
* Specifies the appearance fill style of the Badge ([see example]({% slug appearance_badge %}#toc-fill)).
*
* @default solid
*/
fill = 'solid';
/**
* Specifies the theme color of the Badge.
* The theme color applies as background and border color, while also amending the text color accordingly
* ([see example]({% slug appearance_badge %}#toc-theme-color)).
*
* @default primary
*/
themeColor = 'primary';
/**
* Specifies the roundness of the Badge ([see example]({% slug appearance_badge %}#toc-rounded)).
*
* @default medium
*/
rounded = 'medium';
/**
* Specifies the position of the Badge relative to the edge of the parent container element ([see example]({% slug alignandposition_badge %}#toc-position)).
*
* @default edge
*/
position = 'edge';
/**
* Specifies whether to render additional `cutout` border around the Badge ([see example]({% slug appearance_badge %}#toc-cutout-border)).
*
* @default false
*/
cutoutBorder = false;
badgeClasses = [];
badgeAlign = { vertical: 'top', horizontal: 'end' };
dynamicRTLSubscription;
rtl = false;
constructor(element, renderer, localizationService) {
this.element = element;
this.renderer = renderer;
this.localizationService = localizationService;
validatePackage(packageMetadata);
this.dynamicRTLSubscription = this.localizationService.changes.subscribe(({ rtl }) => {
this.rtl = rtl;
this.direction = this.rtl ? 'rtl' : 'ltr';
});
}
ngAfterViewInit() {
if (!this.badgeClasses.length) {
this.setBadgeClasses();
}
}
ngOnChanges() {
this.setBadgeClasses();
}
ngOnDestroy() {
if (this.dynamicRTLSubscription) {
this.dynamicRTLSubscription.unsubscribe();
}
}
alignClass() {
return `k-${this.badgeAlign.vertical}-${this.badgeAlign.horizontal}`;
}
positionClass() {
return `k-badge-${this.position}`;
}
sizeClass() {
if (this.size !== 'none') {
return SIZE_CLASSES$1[this.size];
}
return '';
}
roundedClass() {
if (this.rounded !== 'none') {
return ROUNDED_CLASSES[this.rounded];
}
return '';
}
themeColorClass() {
if (this.themeColor !== 'none' && this.fill !== 'none') {
return `k-badge-${this.fill}-${this.themeColor}`;
}
return '';
}
fillClass() {
if (this.fill !== 'none') {
return `k-badge-${this.fill}`;
}
return '';
}
setBadgeClasses() {
const element = this.element.nativeElement;
this.badgeClasses.forEach((className) => {
this.renderer.removeClass(element, className);
});
this.badgeClasses = [
this.themeColorClass(),
this.fillClass(),
this.sizeClass(),
this.roundedClass(),
this.alignClass(),
this.positionClass()
];
this.badgeClasses.forEach((className) => {
if (className) {
this.renderer.addClass(element, className);
}
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BadgeComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BadgeComponent, isStandalone: true, selector: "kendo-badge", inputs: { align: "align", size: "size", fill: "fill", themeColor: "themeColor", rounded: "rounded", position: "position", cutoutBorder: "cutoutBorder" }, host: { properties: { "class.k-badge": "this.hostClass", "class.k-badge-border-cutout": "this.cutoutBorderClass", "attr.dir": "this.direction" } }, providers: [
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.badge.component'
}
], usesOnChanges: true, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BadgeComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-badge',
providers: [
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.badge.component'
}
],
template: `<ng-content></ng-content>`,
standalone: true
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.LocalizationService }]; }, propDecorators: { hostClass: [{
type: HostBinding,
args: ['class.k-badge']
}], cutoutBorderClass: [{
type: HostBinding,
args: ['class.k-badge-border-cutout']
}], direction: [{
type: HostBinding,
args: ['attr.dir']
}], align: [{
type: Input
}], size: [{
type: Input
}], fill: [{
type: Input
}], themeColor: [{
type: Input
}], rounded: [{
type: Input
}], position: [{
type: Input
}], cutoutBorder: [{
type: Input
}] } });
const SIZE_CLASSES = {
'small': 'k-loader-sm',
'medium': 'k-loader-md',
'large': 'k-loader-lg'
};
const SEGMENT_COUNT = {
'pulsing': 2,
'infinite-spinner': 3,
'converging-spinner': 4
};
const TYPE_CLASSES = {
'pulsing': 'k-loader-pulsing-2',
'infinite-spinner': 'k-loader-spinner-3',
'converging-spinner': 'k-loader-spinner-4'
};
/**
* Represents the [Kendo UI Loader component for Angular]({% slug overview_loader %}).
* Displays a Loader that represents an indeterminate wait time.
*
* Provides configuration options for animation type, theme color, and size.
*
* @example
* ```html
* <kendo-loader [type]="'infinite-spinner'" [themeColor]="'primary'" [size]="'large'"></kendo-loader>
* ```
*/
class LoaderComponent {
element;
renderer;
hostClass = true;
/**
* Specifies the Loader animation type.
*
* @default pulsing
*/
set type(type) {
this.renderer.removeClass(this.loader, TYPE_CLASSES[this.type]);
this.renderer.addClass(this.loader, TYPE_CLASSES[type]);
this._type = type;
}
get type() {
return this._type;
}
/**
* Specifies the theme color of the Loader.
*
* @default primary
*/
set themeColor(themeColor) {
this.renderer.removeClass(this.loader, `k-loader-${this.themeColor}`);
this.renderer.addClass(this.loader, `k-loader-${themeColor}`);
this._themeColor = themeColor;
}
get themeColor() {
return this._themeColor;
}
/**
* Specifies the size of the Loader.
*
* @default medium
*/
set size(size) {
this.renderer.removeClass(this.loader, SIZE_CLASSES[this.size]);
this.renderer.addClass(this.loader, SIZE_CLASSES[size]);
this._size = size;
}
get size() {
return this._size;
}
_type = 'pulsing';
_themeColor = 'primary';
_size = 'medium';
loader;
constructor(element, renderer) {
this.element = element;
this.renderer = renderer;
validatePackage(packageMetadata);
this.loader = this.element.nativeElement;
}
ngAfterViewInit() {
this.setLoaderClasses();
}
/**
* @hidden
*/
get segmentCount() {
return new Array(SEGMENT_COUNT[this.type]);
}
setLoaderClasses() {
this.renderer.addClass(this.loader, TYPE_CLASSES[this.type]);
this.renderer.addClass(this.loader, `k-loader-${this.themeColor}`);
this.renderer.addClass(this.loader, SIZE_CLASSES[this.size]);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LoaderComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: LoaderComponent, isStandalone: true, selector: "kendo-loader", inputs: { type: "type", themeColor: "themeColor", size: "size" }, host: { properties: { "class.k-loader": "this.hostClass" } }, ngImport: i0, template: `
<div class="k-loader-canvas">
<span *ngFor="let segment of segmentCount" class="k-loader-segment"></span>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LoaderComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-loader',
template: `
<div class="k-loader-canvas">
<span *ngFor="let segment of segmentCount" class="k-loader-segment"></span>
</div>
`,
standalone: true,
imports: [NgFor]
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { hostClass: [{
type: HostBinding,
args: ['class.k-loader']
}], type: [{
type: Input
}], themeColor: [{
type: Input
}], size: [{
type: Input
}] } });
/**
* @hidden
*/
const validAnimations = [false, 'pulse', 'wave'];
/**
* @hidden
*/
const validShapes = ['circle', 'rectangle', 'text'];
/**
* @hidden
*/
const ANIMATION_CLASSES = {
pulse: 'k-skeleton-pulse',
wave: 'k-skeleton-wave'
};
/**
* @hidden
*/
const SHAPE_CLASSES = {
rectangle: 'k-skeleton-rect',
circle: 'k-skeleton-circle',
text: 'k-skeleton-text'
};
/**
* @hidden
*/
const skeletonShapeError = (input) => `"${input}" is not a valid kendo-skeleton shape. Valid shapes are: ${validShapes.map(s => `"${s}"`).join(" | ")}.`;
/**
* @hidden
*/
const skeletonAnimationError = (input) => `"${input}" is not a valid kendo-skeleton animation. Valid values are: 'pulse' | 'wave' | false.`;
/**
* Represents the [Kendo UI Skeleton component for Angular]({% slug overview_skeleton %}).
* Displays a Skeleton placeholder that represents loading content.
*
* Provides configuration options for animation, shape, width, and height.
*
* @example
* ```html
* <kendo-skeleton [shape]="'circle'" [animation]="'wave'" width="40px" height="40px"></kendo-skeleton>
* ```
*/
class SkeletonComponent {
renderer;
hostElement;
/**
* Specifies the animation settings of the Skeleton.
*
* @default pulse
*/
set animation(animation) {
if (isDevMode() && validAnimations.indexOf(animation) === -1) {
throw new Error(skeletonAnimationError(animation));
}
if (this.animation) {
this.renderer.removeClass(this.hostElement.nativeElement, ANIMATION_CLASSES[this.animation]);
}
if (animation) {
this.renderer.addClass(this.hostElement.nativeElement, ANIMATION_CLASSES[animation]);
}
this._animation = animation;
}
get animation() {
return this._animation;
}
/**
* Specifies the shape of the Skeleton.
*
* @default text
*/
set shape(shape) {
if (isDevMode() && validShapes.indexOf(shape) === -1) {
throw new Error(skeletonShapeError(shape));
}
this.renderer.removeClass(this.hostElement.nativeElement, SHAPE_CLASSES[this.shape]);
this.renderer.addClass(this.hostElement.nativeElement, SHAPE_CLASSES[shape]);
this._shape = shape;
}
get shape() {
return this._shape;
}
/**
* Specifies the width of the Skeleton component.
* Required for all Skeleton shapes.
* Accepts a string like `100px`, `3em`, or `50%`, or an integer number for pixels.
*/
set width(width) {
this.renderer.setStyle(this.hostElement.nativeElement, "width", typeof width === "string" ? width : width + "px");
}
/**
* Specifies the height of the Skeleton component.
* Required for `circle` and `rectangle` shapes.
* Not required for `text`, as it derives from the current CSS font-size.
* Accepts a string like `100px`, `3em`, or `50%`, or an integer number for pixels.
*/
set height(height) {
this.renderer.setStyle(this.hostElement.nativeElement, "height", typeof height === "string" ? height : height + "px");
}
_animation = "pulse";
_shape = 'text';
constructor(renderer, hostElement) {
this.renderer = renderer;
this.hostElement = hostElement;
}
ngAfterViewInit() {
const hostElement = this.hostElement.nativeElement;
hostElement.classList.add("k-skeleton", SHAPE_CLASSES[this.shape]);
if (this.animation) {
hostElement.classList.add(ANIMATION_CLASSES[this.animation]);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SkeletonComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SkeletonComponent, isStandalone: true, selector: "kendo-skeleton", inputs: { animation: "animation", shape: "shape", width: "width", height: "height" }, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SkeletonComponent, decorators: [{
type: Component,
args: [{
selector: "kendo-skeleton",
changeDetection: ChangeDetectionStrategy.OnPush,
template: ``,
standalone: true
}]
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { animation: [{
type: Input
}], shape: [{
type: Input
}], width: [{
type: Input
}], height: [{
type: Input
}] } });
/**
* Utility array that contains all `Badge` related components and directives.
*/
const KENDO_BADGE = [
BadgeComponent
];
/**
* Utility array that contains all `BadgeContainer` related components and directives.
*/
const KENDO_BADGECONTAINER = [
BadgeComponent,
BadgeContainerComponent
];
/**
* Utility array that contains all `Loader` related components and directives.
*/
const KENDO_LOADER = [
LoaderComponent
];
/**
* Utility array that contains all `Skeleton` related components and directives.
*/
const KENDO_SKELETON = [
SkeletonComponent
];
/**
* Utility array that contains all `@progress/kendo-angular-indicators` related components and directives.
*/
const KENDO_INDICATORS = [
...KENDO_BADGECONTAINER,
...KENDO_LOADER,
...KENDO_SKELETON
];
// IMPORTANT: NgModule export kept for backwards compatibility
/**
* Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
* definition for the Badge and BadgeContainer components.
*/
class BadgeModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BadgeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: BadgeModule, imports: [BadgeComponent, BadgeContainerComponent], exports: [BadgeComponent, BadgeContainerComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BadgeModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BadgeModule, decorators: [{
type: NgModule,
args: [{
exports: [...KENDO_BADGECONTAINER],
imports: [...KENDO_BADGECONTAINER]
}]
}] });
// IMPORTANT: NgModule export kept for backwards compatibility
/**
* Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
* definition for the Loader component.
*/
class LoaderModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LoaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: LoaderModule, imports: [LoaderComponent], exports: [LoaderComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LoaderModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LoaderModule, decorators: [{
type: NgModule,
args: [{
exports: [...KENDO_LOADER],
imports: [...KENDO_LOADER]
}]
}] });
// IMPORTANT: NgModule export kept for backwards compatibility
/**
* Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
* definition for the Skeleton component.
*/
class SkeletonModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SkeletonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: SkeletonModule, imports: [SkeletonComponent], exports: [SkeletonComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SkeletonModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SkeletonModule, decorators: [{
type: NgModule,
args: [{
exports: [...KENDO_SKELETON],
imports: [...KENDO_SKELETON]
}]
}] });
// IMPORTANT: NgModule export kept for backwards compatibility
/**
* Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
* definition for the Indicators components.
*
* @example
*
* ```ts-no-run
* import { IndicatorsModule } from '@progress/kendo-angular-indicators';
* import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
* import { NgModule } from '@angular/core';
* import { AppComponent } from './app.component';
*
* @NgModule({
* declarations: [AppComponent],
* imports: [BrowserModule, IndicatorsModule],
* bootstrap: [AppComponent]
* })
* export class AppModule {}
*
* platformBrowserDynamic().bootstrapModule(AppModule);
* ```
*/
class IndicatorsModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IndicatorsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: IndicatorsModule, imports: [BadgeComponent, BadgeContainerComponent, LoaderComponent, SkeletonComponent], exports: [BadgeComponent, BadgeContainerComponent, LoaderComponent, SkeletonComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IndicatorsModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IndicatorsModule, decorators: [{
type: NgModule,
args: [{
imports: [...KENDO_INDICATORS],
exports: [...KENDO_INDICATORS]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { BadgeComponent, BadgeContainerComponent, BadgeModule, IndicatorsModule, KENDO_BADGE, KENDO_BADGECONTAINER, KENDO_INDICATORS, KENDO_LOADER, KENDO_SKELETON, LoaderComponent, LoaderModule, SkeletonComponent, SkeletonModule };