File

lib/common/src/widgets/widgets.commons.ts

Description

Every custom widget component class has to have the static property and the static method of this interface.

More on Widgets

Index

Properties

Properties

controlType
controlType: Type<C>
Type : Type<C>
label
label: string
Type : string
Optional
widgetMatch
widgetMatch: WidgetMatchFn<C>
Type : WidgetMatchFn<C>
import	{	
			Type,
			InjectionToken,
			Directive
		}							from '@angular/core'

import	{	assert			}		from '@rcc/core'



/**  
 * Represents any kind of WidgetControl. 
 * This class is meant to be extended and not to be instantiated on its own. 
 * Every time you want to create a new type of widget, you should define a control class extending this base class.
 * A control class defined this way will serve as indicator of your widget type and consists of all the data and methods, 
 * widgets of your new widget type can make use of.
 * 
 * This class does nothing on its own. {@link /modules/WidgetsModule.html#readme | Howto Widgets}
 */
export class WidgetControl{}










/**
 * A method that evaluates how well the parent object suits a given instance of a {@link WidgetControl} extension.
 * 
 * Return values are interpreted like this:
 * 
 * ```  
 *   -1: can't handle this kind of WidgetControl instance 
 *    0: can handle this kind of WidgetControl instance - if need be 
 *    1: good at handling this kind of WidgetControl instance 
 * >= 2: specifically made to handle this kind of WidgetControl instance 
 * ```
 * You should very rarely return a value greater than 2.
 * 
 * {@link WidgetsModule|More on Widgets}
 */ 
export type WidgetMatchFn<C extends WidgetControl> = (control : C) => number 









/**
 * Every custom widget component class has to have the static property and the static method of this interface.
 * 
 * {@link /modules/WidgetsModule.html#readme | More on Widgets} 
 */
  
 
export interface WidgetComponentType<C extends WidgetControl = WidgetControl>{

	label?		: string
	controlType : Type<C>    
	widgetMatch : WidgetMatchFn<C>

    new (widgetControl: C): WidgetComponent<C>
}





/** 
 * Every custom WidgetComponent has to extend this class.
 * {@link /modules/WidgetsModule.html#readme | More on Widgets} 
 * 
 * And every extension has to have the following static property and method matching your extension of WidgetControl `MyWidgetControl extends WidgetControl`:
 * ```ts
 * 
 *	class MyWidgetComponent<MyWidgetControl> extends WidgetComponent<MyWidgetControl>{
 * 
 *		static controlType : Type<MyWidgetControl>    
 * 		static widgetMatch : WidgetMatchFn<MyWidgetControl>
 * 		
 * 		constructor(myWidgetControl: MyWidgetControl){
 *			super(myWidgetControl) 
 * 			...
 * 		}
 *	}
 * ```
 * 
 * 
 */ 
 @Directive()
export class WidgetComponent<C extends WidgetControl> {

	static label		: string

	static controlType 	: Type<unknown>
	static widgetMatch 	: WidgetMatchFn<unknown> = () => { throw "WidgetComponent missing static widgetMatch()" }


	constructor(widgetControl: C){


		const staticSelf		        = (this.constructor as WidgetComponentType<C>)
		const widgetComponentTypeName	= staticSelf.name
		const expectedControlType		= staticSelf.controlType
		const actualControlType			= widgetControl.constructor

		assert(widgetControl, 								`${widgetComponentTypeName} -> WidgetComponent.constructor missing static idgetControl.`)
		assert(expectedControlType, 						`${widgetComponentTypeName} -> WidgetComponent.constructor missing static controlType`)
		assert(expectedControlType == actualControlType,	`${widgetComponentTypeName} -> WidgetComponent.constructor controlType mismatch: expected ${expectedControlType.name}, got ${actualControlType.name} instead.`)

		assert(staticSelf.widgetMatch(widgetControl) >= 0,	`${widgetComponentTypeName} -> WidgetComponent.constructor() control mismatch.`)

	}

}








/**
 * Token to register WidgetCompoents.{@link WidgetsModule|More on Widgets}. Don't use this on it's own, instead use {@link provideWidgets}
 */
 export const WIDGETS = new InjectionToken<Type<WidgetComponent<unknown>>>('WidgetComponents')







/**
 * Registers {@link WidgetComponent}s to be used by {@link RccWidgetComponent}. 
 * 
 * * ```
 * @NgModule({
 * 	providers: [
 * 		provideWidgets(MyTranslator, ...),
 * 		...
 * 	],
 * 	...
 * })
 * ```
 */	 
export function provideWidget(widgetComponent: Type<WidgetComponent<unknown>>){

	assert(typeof (widgetComponent as any).controlType == 'function', 'provideWidget: provided widgetComponent lacks static property "controlType"')

	return	{
				provide:	WIDGETS,
				useValue:	widgetComponent,
				multi:		true
			}
				
}

results matching ""

    No results matching ""