import { Component, h, Prop, Listen, State, Watch } from '@stencil/core'; import { Language } from '../../utils/common/language-types'; import { validateLanguage } from '../../utils/validation/validation-functions'; import { validateValueAgainstArray } from '../../utils/validation/validation-functions'; import { ConsoleMessageClass } from '../../utils/console-message/console-message'; import { HeaderLanguageToggleEventDetails } from '../../utils/events/common-events.interface'; import translations from '../../translations/global.i18n.json'; /** * Ontario Loading Indicator communicates in-progress loading states. * * For component guidance, see: * - https://designsystem.ontario.ca/components/detail/loading-indicator.html * - https://designsystem.ontario.ca/developer-docs/components/ontario-loading-indicator/ */ @Component({ tag: 'ontario-loading-indicator', styleUrl: 'ontario-loading-indicator.scss', shadow: true, }) export class OntarioLoadingIndicator { /** * The type of loading indicator to render. */ @Prop() type: 'small' | 'large' = 'large'; /** * A boolean value to determine whether or not the loading indicator is loading (i.e: is visible) or not. */ @Prop() isLoading: boolean = false; /** * The message that tells the user what is happening or why the user is waiting. * If no message prop is passed, it will default to "Loading". Translations for this default message are included. * * This is optional. */ @Prop() message?: string; /** * A boolean value to determine whether the loading indicator overlay covers the full page or not. By default, this is set to `true`. * * If set to `false`, the loading indicator overlay will be positioned absolutely relative to its container. Note that this will only work if the containing element has a style rule specifying it to be positioned relatively. */ @Prop() fullScreenOverlay?: boolean = true; /** * The language of the component. * This is used for translations, and is by default set through event listeners checking for a language property from the header. If no language is passed, it will default to English. */ @Prop({ mutable: true }) language?: Language; @State() translations: any = translations; /** * Mutable variables, for internal use only. */ @State() private isLoadingState: boolean; @State() private typeState: 'small' | 'large'; /** * This listens for the `setAppLanguage` event sent from the test language toggler when it is is connected to the DOM. It is used for the initial language when the input component loads. */ @Listen('setAppLanguage', { target: 'window' }) handleSetAppLanguage(event: CustomEvent) { if (!this.language) { this.language = validateLanguage(event); } } /** * Handles an update to the language should the user request a language update from the language toggle. * @param {CustomEvent} - The language that has been selected. */ @Listen('headerLanguageToggled', { target: 'window' }) handleHeaderLanguageToggled(event: CustomEvent) { this.language = validateLanguage(event.detail.newLanguage); } /** * Watch for changes in the `isLoading` prop. */ @Watch('isLoading') isLoadingChanged(newIsLoading: boolean) { this.isLoadingState = newIsLoading; } /** * Watch for changes in the `type` variable for validation purposes. * * If the user input doesn't match one of the array values then `type` will be set to its default (`large`). * If a match is found in one of the array values then `type` will be set to the matching array key value. */ @Watch('type') validateType() { const isValid = validateValueAgainstArray(this.type, ['large', 'small']); if (isValid) { return (this.typeState = this.type); } else { this.warnDefaultType(); return (this.typeState = 'large'); } } /** * Print the invalid `type` warning message. * @returns default type ('large') */ private warnDefaultType() { const message = new ConsoleMessageClass(); message .addDesignSystemTag() .addMonospaceText(' type ') .addRegularText('on') .addMonospaceText(' ') .addRegularText('was set to an invalid type; only') .addMonospaceText(' large or small ') .addRegularText('are supported. The default type') .addMonospaceText(' large ') .addRegularText('is assumed.') .printMessage(); } componentWillLoad() { this.language = validateLanguage(this.language); this.validateType(); this.isLoadingState = this.isLoading; } render() { return this.typeState === 'large' ? ( ) : (

The small loading indicator is still under development.

); } }