UNPKG

@v4fire/client

Version:

V4Fire client core library

165 lines (143 loc) 3.93 kB
/*! * V4Fire Client Core * https://github.com/V4Fire/Client * * Released under the MIT license * https://github.com/V4Fire/Client/blob/master/LICENSE */ import symbolGenerator from 'core/symbol'; import type { AsyncOptions } from 'core/async'; import Friend from 'super/i-block/modules/friend'; import type bVirtualScrollNew from 'base/b-virtual-scroll-new/b-virtual-scroll-new'; import type { SlotsStateObj } from 'base/b-virtual-scroll-new/modules/slots/interface'; export * from 'base/b-virtual-scroll-new/modules/slots/interface'; export const $$ = symbolGenerator(), slotsStateControllerAsyncGroup = 'slotsStateController'; /** * A class that manages the visibility of slots based on different states. */ export class SlotsStateController extends Friend { override readonly C!: bVirtualScrollNew; /** * Options for the asynchronous operations. */ protected readonly asyncUpdateLabel: AsyncOptions = { label: $$.updateSlotsVisibility, group: slotsStateControllerAsyncGroup }; /** * The last state of the slots. */ protected lastState?: SlotsStateObj; /** * Displays the slots that should be shown when the data state is empty */ emptyState(): void { this.setSlotsVisibility({ container: true, done: true, empty: true, loader: false, renderNext: false, retry: false, tombstones: false }); } /** * Displays the slots that should be shown when the lifecycle is done */ doneState(): void { this.setSlotsVisibility({ container: true, done: true, empty: this.lastState?.empty ?? false, loader: false, renderNext: false, retry: false, tombstones: false }); } /** * Displays the slots that should be shown during data loading progress * @param [immediate] - if set to true, {@link requestAnimationFrame} will not be used to switch the state. */ loadingProgressState(immediate: boolean = false): void { this.setSlotsVisibility({ container: true, loader: true, tombstones: true, done: false, empty: false, renderNext: false, retry: false }, immediate); } /** * Displays the slots that should be shown when data loading fails */ loadingFailedState(): void { this.setSlotsVisibility({ container: true, retry: true, done: false, empty: false, loader: false, renderNext: false, tombstones: false }); } /** * Displays the slots that should be shown when data loading is successful * @param immediate */ loadingSuccessState(immediate: boolean = false): void { this.setSlotsVisibility({ container: true, done: false, empty: false, loader: false, renderNext: true, retry: false, tombstones: false }, immediate); } /** * Resets the state of the module */ reset(): void { this.async.clearAll({group: new RegExp(slotsStateControllerAsyncGroup)}); this.lastState = undefined; } /** * Sets the visibility state of the slots. * * @param stateObj - an object specifying the visibility state of each slot. * @param [immediate] - if set to true, {@link requestAnimationFrame} will not be used to switch the state. */ protected setSlotsVisibility(stateObj: Required<SlotsStateObj>, immediate: boolean = false): void { this.lastState = stateObj; this.async.cancelAnimationFrame(this.asyncUpdateLabel); const update = () => { for (const [name, state] of Object.entries(stateObj)) { this.setDisplayState(<keyof SlotsStateObj>name, state); } }; if (immediate) { return update(); } this.async.requestAnimationFrame(update, this.asyncUpdateLabel); } /** * Sets the display state of a slot. * * @param name - the name of the slot. * @param state - the visibility state of the slot. */ protected setDisplayState(name: keyof SlotsStateObj, state: boolean): void { const ref = this.ctx.$refs[name]; if (ref instanceof HTMLElement) { ref.style.display = state ? '' : 'none'; } } }