import * as i0 from '@angular/core'; import { InjectionToken, inject, input, numberAttribute, computed, isDevMode, ChangeDetectionStrategy, Component, NgModule, makeEnvironmentProviders } from '@angular/core'; const NGX_SKELETON_LOADER_CONFIG = new InjectionToken('ngx-skeleton-loader.config'); /** * The `NgxSkeletonLoaderComponent` is a standalone Angular component that provides a skeleton * loader UI element. * It can be used to display a loading state before the actual content is available. * The component can be configured with various options such as the number of elements, appearance, * animation, and theme. */ class NgxSkeletonLoaderComponent { constructor() { /** * Injects the `NgxSkeletonLoaderConfig` configuration object, which is optional. * This configuration object provides various options for customizing the behavior * and appearance of the `NgxSkeletonLoaderComponent`. */ this.#config = inject(NGX_SKELETON_LOADER_CONFIG, { optional: true }); /** * The `count` property is an input that determines the number of skeleton loader elements * to display. * It is initialized with the value from the `NgxSkeletonLoaderConfig` object, or 1 if the config * is not provided. * The `transform: numberAttribute` option ensures that the input value is converted to a number. */ this.count = input(this.#config?.count || 1, { ...(ngDevMode ? { debugName: "count" } : {}), transform: numberAttribute }); /** * The `loadingText` property is an input that determines the text to display while the content * is loading. * It is initialized with the value from the `NgxSkeletonLoaderConfig` object, or 'Loading...' * if the config is not provided. */ this.loadingText = input(this.#config?.loadingText || 'Loading...', { ...(ngDevMode ? { debugName: "loadingText" } : {}) }); /** * The `appearance` property is an input that determines the visual appearance of the skeleton * loader. * It is initialized with the value from the `NgxSkeletonLoaderConfig` object, or 'line' if the * config is not provided. * The available appearance options are defined in the `NgxSkeletonLoaderConfig['appearance']` * type. */ this.appearance = input(this.#config?.appearance || 'line', { ...(ngDevMode ? { debugName: "appearance" } : {}) }); /** * The `animation` property is an input that determines the type of animation to apply to the * skeleton loader. * It is initialized with the value from the `NgxSkeletonLoaderConfig` object, or 'progress' if * the config is not provided. * The available animation options are defined in the `NgxSkeletonLoaderConfig['animation']` type. */ this.animation = input(this.#config?.animation || 'progress', { ...(ngDevMode ? { debugName: "animation" } : {}) }); /** * The `ariaLabel` property is an input that determines the ARIA label to be used for the skeleton * loader element. This is useful for providing accessibility information to screen readers. * It is initialized with the value from the `NgxSkeletonLoaderConfig` object, or 'loading' if the * config is not provided. */ this.ariaLabel = input(this.#config?.ariaLabel || 'loading', { ...(ngDevMode ? { debugName: "ariaLabel" } : {}) }); /** * The `theme` property is an input that determines the theme configuration for the skeleton * loader. * It is initialized with the value from the `NgxSkeletonLoaderConfig` object, or `null` if the * config is not provided. * The theme configuration is defined by the `NgxSkeletonLoaderConfigTheme` type, which allows * customizing various aspects of the skeleton loader's appearance, such as colors, animation, * etc. */ this.theme = input(this.#config?.theme || null, { ...(ngDevMode ? { debugName: "theme" } : {}) }); /** * The `size` property is an input that determines the size of the skeleton loader. * It is initialized with the value from the `NgxSkeletonLoaderConfig` object, or `null` if the * config is not provided. * The size can be specified as a number (in pixels) (e.g., '50', '200'). */ this.size = input(this.#config?.size || null, { ...(ngDevMode ? { debugName: "size" } : {}) }); /** * The `measureUnit` property is an input that determines the unit of measurement for the size * of the skeleton loader. * It is initialized with the value from the `NgxSkeletonLoaderConfig` object, or 'px' if the * config is not provided. * This allows the size to be specified in different units, such as 'px', 'em', etc. */ this.measureUnit = input(this.#config?.measureUnit || 'px', { ...(ngDevMode ? { debugName: "measureUnit" } : {}) }); /** * The `items` property is a computed property that generates an array of indices based on the * `count` input. * If the `appearance` is set to 'custom-content', the `count` is forced to 1 to ensure that the * skeleton loader is displayed as a single DOM node, as required by the 'custom-content' * appearance. * This computed property is used to render the appropriate number of skeleton loader elements. */ this.items = computed(() => { let count = this.count() || 1; // Force count to 1 when custom-content is used if (this.appearance() === 'custom-content') { // Shows error message only in Development if (isDevMode() && count !== 1) { // eslint-disable-next-line no-console console.error(`\`NgxSkeletonLoaderComponent\` enforces elements with "custom-content" appearance as DOM nodes. Forcing "count" to "1".`); count = 1; } } return [...Array(count)].map((_, index) => index); }, { ...(ngDevMode ? { debugName: "items" } : {}) }); /** * The `squareSize` property is a computed property that calculates the size of the skeleton * loader when the appearance is set to 'square'. * It checks the `size` input and ensures that it is a valid number or string representing a * valid pixel value. If the `size` is not a valid number or string, it returns `null`. * If the `appearance` is not 'square', it also returns `null`. * This computed property is used to set the width and height of the skeleton loader when it * is displayed as a square. */ this.squareSize = computed(() => { const size = this.size(); if (this.appearance() !== 'square' || (typeof size !== 'number' && typeof size !== 'string')) { return null; } const sizeValueInNumbersOnly = Number(size.toString().trim().replace(/\D/g, '')); if (!Number.isInteger(sizeValueInNumbersOnly)) { return null; } return `${sizeValueInNumbersOnly}${this.measureUnit()}`; }, { ...(ngDevMode ? { debugName: "squareSize" } : {}) }); /** * A computed property that returns the final theme configuration for the skeleton loader. * If the `extendsFromRoot` property is set in the `NgxSkeletonLoaderConfig`, the theme is merged * with the root theme configuration. Otherwise, the theme is returned as-is. * This allows the skeleton loader to inherit global theme settings while still allowing for * component-specific theme customization. */ this.styles = computed(() => { const theme = this.theme(); const size = this.squareSize(); if (this.#config?.theme?.extendsFromRoot) { return { ...this.#config?.theme, ...theme, ...(size && { width: size, height: size }), }; } return { ...theme, ...(size && { width: size, height: size }), }; }, { ...(ngDevMode ? { debugName: "styles" } : {}) }); } /** * Injects the `NgxSkeletonLoaderConfig` configuration object, which is optional. * This configuration object provides various options for customizing the behavior * and appearance of the `NgxSkeletonLoaderComponent`. */ #config; static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxSkeletonLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: NgxSkeletonLoaderComponent, isStandalone: true, selector: "ngx-skeleton-loader", inputs: { count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, measureUnit: { classPropertyName: "measureUnit", publicName: "measureUnit", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let appearanceValue = appearance();\n@let animationValue = animation();\n@for (item of items(); track item) {\n