96 lines
3.7 KiB
TypeScript
96 lines
3.7 KiB
TypeScript
import { Observable } from 'rxjs';
|
|
|
|
import type { HTMLElementConstructor } from '../models';
|
|
|
|
import { UmbControllerHostInterface, UmbControllerHostMixin } from '@umbraco-cms/controller';
|
|
import {
|
|
ContextAlias,
|
|
UmbContextCallback,
|
|
UmbContextConsumerController,
|
|
UmbContextProviderController,
|
|
} from '@umbraco-cms/context-api';
|
|
import { UmbObserverController } from '@umbraco-cms/observable-api';
|
|
|
|
// TODO: can we use this aliases to generate the key of this type
|
|
interface ResolvedContexts {
|
|
[key: string]: any;
|
|
}
|
|
|
|
export declare class UmbElementMixinInterface extends UmbControllerHostInterface {
|
|
observe<T>(source: Observable<T>, callback: (_value: T) => void, unique?: string): UmbObserverController<T>;
|
|
provideContext<R = unknown>(alias: string | ContextAlias<R>, instance: R): UmbContextProviderController<R>;
|
|
consumeContext<R = unknown>(
|
|
alias: string | ContextAlias<R>,
|
|
callback: UmbContextCallback<R>
|
|
): UmbContextConsumerController<R>;
|
|
consumeAllContexts(contextAliases: string[], callback: (_instances: ResolvedContexts) => void): void;
|
|
}
|
|
|
|
export const UmbElementMixin = <T extends HTMLElementConstructor>(superClass: T) => {
|
|
class UmbElementMixinClass extends UmbControllerHostMixin(superClass) implements UmbElementMixinInterface {
|
|
/**
|
|
* @description Observe a RxJS source of choice.
|
|
* @param {Observable<T>} source RxJS source
|
|
* @param {method} callback Callback method called when data is changed.
|
|
* @return {UmbObserverController} Reference to a Observer Controller instance
|
|
* @memberof UmbElementMixin
|
|
*/
|
|
observe<T>(source: Observable<T>, callback: (_value: T) => void, unique?: string): UmbObserverController<T> {
|
|
return new UmbObserverController<T>(this, source, callback, unique);
|
|
}
|
|
|
|
/**
|
|
* @description Provide a context API for this or child elements.
|
|
* @param {string} alias
|
|
* @param {instance} instance The API instance to be exposed.
|
|
* @return {UmbContextProviderController} Reference to a Context Provider Controller instance
|
|
* @memberof UmbElementMixin
|
|
*/
|
|
provideContext<R = unknown>(alias: string | ContextAlias<R>, instance: R): UmbContextProviderController<R> {
|
|
return new UmbContextProviderController(this, alias, instance);
|
|
}
|
|
|
|
/**
|
|
* @description Setup a subscription for a context. The callback is called when the context is resolved.
|
|
* @param {string} alias
|
|
* @param {method} callback Callback method called when context is resolved.
|
|
* @return {UmbContextConsumerController} Reference to a Context Consumer Controller instance
|
|
* @memberof UmbElementMixin
|
|
*/
|
|
consumeContext<R = unknown>(
|
|
alias: string | ContextAlias<R>,
|
|
callback: UmbContextCallback<R>
|
|
): UmbContextConsumerController<R> {
|
|
return new UmbContextConsumerController(this, alias, callback);
|
|
}
|
|
|
|
/**
|
|
* @description Setup a subscription for multiple contexts. The callback is called when all contexts are resolved.
|
|
* @param {string} aliases
|
|
* @param {method} callback Callback method called when all contexts are resolved.
|
|
* @memberof UmbElementMixin
|
|
*/
|
|
consumeAllContexts(_contextAliases: Array<string>, callback: (_instances: ResolvedContexts) => void) {
|
|
let resolvedAmount = 0;
|
|
const controllers = _contextAliases.map(
|
|
(alias) =>
|
|
new UmbContextConsumerController(this, alias, () => {
|
|
resolvedAmount++;
|
|
|
|
if (resolvedAmount === _contextAliases.length) {
|
|
const result: ResolvedContexts = {};
|
|
|
|
controllers.forEach((contextCtrl: UmbContextConsumerController) => {
|
|
result[contextCtrl.consumerAlias?.toString()] = contextCtrl.instance;
|
|
});
|
|
|
|
callback(result);
|
|
}
|
|
})
|
|
);
|
|
}
|
|
}
|
|
|
|
return UmbElementMixinClass as unknown as HTMLElementConstructor<UmbElementMixinInterface> & T;
|
|
};
|