Files
Umbraco-CMS/src/Umbraco.Web.UI.Client/libs/element/element.mixin.ts

97 lines
3.8 KiB
TypeScript
Raw Normal View History

2023-01-02 16:21:35 +01:00
import { Observable } from 'rxjs';
2023-01-23 15:01:47 +01:00
import type { HTMLElementConstructor } from '@umbraco-cms/models';
import { UmbControllerHostInterface, UmbControllerHostMixin } from '@umbraco-cms/controller';
import {
UmbContextToken,
UmbContextCallback,
UmbContextConsumerController,
UmbContextProviderController,
} from '@umbraco-cms/context-api';
import { UmbObserverController } from '@umbraco-cms/observable-api';
2023-01-02 16:11:17 +01:00
// 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 | UmbContextToken<R>, instance: R): UmbContextProviderController<R>;
consumeContext<R = unknown>(
alias: string | UmbContextToken<R>,
callback: UmbContextCallback<R>
): UmbContextConsumerController<R>;
2023-01-02 16:11:17 +01:00
consumeAllContexts(contextAliases: string[], callback: (_instances: ResolvedContexts) => void): void;
}
export const UmbElementMixin = <T extends HTMLElementConstructor>(superClass: T) => {
class UmbElementMixinClass extends UmbControllerHostMixin(superClass) implements UmbElementMixinInterface {
2023-01-02 16:21:35 +01:00
/**
2023-01-02 20:54:55 +01:00
* @description Observe a RxJS source of choice.
2023-01-02 21:29:16 +01:00
* @param {Observable<T>} source RxJS source
2023-01-02 16:21:35 +01:00
* @param {method} callback Callback method called when data is changed.
2023-01-02 20:54:55 +01:00
* @return {UmbObserverController} Reference to a Observer Controller instance
* @memberof UmbElementMixin
2023-01-02 16:21:35 +01:00
*/
observe<T>(source: Observable<T>, callback: (_value: T) => void, unique?: string): UmbObserverController<T> {
return new UmbObserverController<T>(this, source, callback, unique);
2023-01-02 16:21:35 +01:00
}
2023-01-02 16:17:34 +01:00
/**
2023-01-02 20:54:55 +01:00
* @description Provide a context API for this or child elements.
2023-01-02 16:17:34 +01:00
* @param {string} alias
* @param {instance} instance The API instance to be exposed.
2023-01-02 20:54:55 +01:00
* @return {UmbContextProviderController} Reference to a Context Provider Controller instance
* @memberof UmbElementMixin
2023-01-02 16:17:34 +01:00
*/
provideContext<R = unknown>(alias: string | UmbContextToken<R>, instance: R): UmbContextProviderController<R> {
2023-01-02 16:21:35 +01:00
return new UmbContextProviderController(this, alias, instance);
2023-01-02 16:17:34 +01:00
}
2023-01-10 21:54:53 +01:00
2023-01-02 16:11:17 +01:00
/**
2023-01-02 20:54:55 +01:00
* @description Setup a subscription for a context. The callback is called when the context is resolved.
2023-01-02 16:11:17 +01:00
* @param {string} alias
* @param {method} callback Callback method called when context is resolved.
2023-01-02 20:54:55 +01:00
* @return {UmbContextConsumerController} Reference to a Context Consumer Controller instance
* @memberof UmbElementMixin
2023-01-02 16:11:17 +01:00
*/
consumeContext<R = unknown>(
alias: string | UmbContextToken<R>,
callback: UmbContextCallback<R>
): UmbContextConsumerController<R> {
2023-01-02 16:21:35 +01:00
return new UmbContextConsumerController(this, alias, callback);
2023-01-02 16:11:17 +01:00
}
/**
2023-01-02 20:54:55 +01:00
* @description Setup a subscription for multiple contexts. The callback is called when all contexts are resolved.
2023-01-02 16:11:17 +01:00
* @param {string} aliases
* @param {method} callback Callback method called when all contexts are resolved.
2023-01-02 20:54:55 +01:00
* @memberof UmbElementMixin
* @deprecated it should not be necessary to consume multiple contexts at once, use consumeContext instead with an UmbContextToken
2023-01-02 16:11:17 +01:00
*/
consumeAllContexts(_contextAliases: Array<string>, callback: (_instances: ResolvedContexts) => void) {
let resolvedAmount = 0;
const controllers = _contextAliases.map(
(alias) =>
new UmbContextConsumerController(this, alias, () => {
resolvedAmount++;
2023-01-10 21:54:53 +01:00
if (resolvedAmount === _contextAliases.length) {
const result: ResolvedContexts = {};
2023-01-03 11:51:09 +01:00
controllers.forEach((contextCtrl: UmbContextConsumerController) => {
result[contextCtrl.consumerAlias?.toString()] = contextCtrl.instance;
});
2023-01-03 11:51:09 +01:00
callback(result);
}
})
2023-01-02 16:11:17 +01:00
);
}
}
return UmbElementMixinClass as unknown as HTMLElementConstructor<UmbElementMixinInterface> & T;
};