UNPKG

@progress/kendo-angular-indicators

Version:

Kendo UI Indicators for Angular

732 lines (716 loc) 27.5 kB
/**----------------------------------------------------------------------------------------- * 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'; 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: 1749540044, version: '19.1.1', 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 %}). * Used to display additional information or status that is related to an element. */ 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)). * * The possible values are: * * `{ vertical: 'top', horizontal: 'end' }` * * `{ vertical: 'top', horizontal: 'start' }` * * `{ vertical: 'bottom', horizontal: 'start' }` * * `{ vertical: 'bottom', horizontal: 'end' }` * * @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)). * * The possible values are: * * `small` * * `medium` * * `large` * * `none` * * @default medium */ size = 'medium'; /** * Specifies the appearance fill style of the Badge ([see example]({% slug appearance_badge %}#toc-fill)). * * The possible values are: * * `solid` * * `outline` * * `none` * * @default solid */ fill = 'solid'; /** * Specifies the theme color of the Badge. * The theme color will be applied as background and border color, while also amending the text color accordingly * ([see example]({% slug appearance_badge %}#toc-theme-color)). * * The possible values are: * * `primary` * * `secondary` * * `tertiary` * * `inherit` * * `info` * * `success` * * `warning` * * `error` * * `dark` * * `light` * * `inverse` * * `none` * * @default primary */ themeColor = 'primary'; /** * Specifies the roundness of the Badge ([see example]({% slug appearance_badge %}#toc-rounded)). * * The possible values are: * * `small` * * `medium` * * `large` * * `full` * * `none` * * @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)). * * The possible values are: * * `edge` * * `inside` * * `outside` * * @default edge */ position = 'edge'; /** * Specifies whether or not to render additional `cutout` border around the Badge ([see example]({% slug appearance_badge %}#toc-cutout-border)). * * The possible values are: * * `true` * * `false` * * @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. */ class LoaderComponent { element; renderer; hostClass = true; /** * Specifies the Loader animation type. * * The possible values are: * - `pulsing` (default) * - `infinite-spinner` * - `converging-spinner` */ 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. * * The possible values are: * * `primary` (Default)&mdash;Applies coloring based on primary theme color. * * `secondary`&mdash;Applies coloring based on secondary theme color. * * `tertiary`&mdash; Applies coloring based on tertiary theme color. * * `info`&mdash;Applies coloring based on info theme color. * * `success`&mdash; Applies coloring based on success theme color. * * `warning`&mdash; Applies coloring based on warning theme color. * * `error`&mdash; Applies coloring based on error theme color. * * `dark`&mdash; Applies coloring based on dark theme color. * * `light`&mdash; Applies coloring based on light theme color. * * `inverse`&mdash; Applies coloring based on inverted theme color. * */ 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. * * The possible values are: * * `small` * * `medium` (Default) * * `large` * */ 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 that represents loading content. */ class SkeletonComponent { renderer; hostElement; /** * Specifies the animation settings of the Skeleton. * * The possible values are: * * `pulse` &mdash; (Default) Shows a pulse animation effect. * * `wave` &mdash; Shows a wave animation effect. * * `false` &mdash; Disables the animation. Note that it's a boolean, not a string. */ 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. * * The possible values are: * * `text` &mdash; (Default) Renders a line Skeleton. * * `circle` &mdash; Renders a circular Skeleton. * * `rectangle` &mdash; Renders a rectangular Skeleton. */ 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. * * Can be set to a string, e.g. '100px', '3em', '50%'. * * Can be set to an integer number (will be read as width in 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 is derived from the current CSS font-size. * * Can be set to a string, e.g. '100px', '3em', '50%'. * * Can be set to an integer number (will be read as height in 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 the Indicators module * import { IndicatorsModule } from '@progress/kendo-angular-indicators'; * * // The browser platform with a compiler * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; * * import { NgModule } from '@angular/core'; * * // Import the app component * import { AppComponent } from './app.component'; * * // Define the app module * _@NgModule({ * declarations: [AppComponent], // declare app component * imports: [BrowserModule, IndicatorsModule], // import Indicators module * bootstrap: [AppComponent] * }) * export class AppModule {} * * // Compile and launch the module * 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 };