A (form) designer and runtime environment need component meta data to be able to handle a component.

On the web are some specifications arising like:

http://www.openajax.org/member/wiki/OpenAjax_Metadata_1.0_Specification_Widget_Overview (thanks to Paul for pointing us to this one)

At time of writing these seem overly complex when using angular directives...

Definition

A simple metadata specification is expressed in json format. (called the .spec definition file)

The specification defines:

{
	"name": "String simple name of the component",
	"displayName": "String more descriptive name that is shown in the designer",
	"icon": "A reference to the icon shown in designer" ,
	"definition": "A reference to the js file of this component",
	"libraries": Array of js/css definitions (map with 'name'-the lib name, 'version'-the lib version, 'url'-the lib url, 'mimetype'-the lib mimetype, one of 'text/javascript' or 'text/css') that needs to be included for this component,
	"model": {
	  "propertyName": type description, optional default value
	},
	"handlers": {
	  "functionName": "function type"
	},
	"api": {
	  "functionName": signature description json
	},
	"types": {
	   "typename": {
	     "model": {
	        "propertyName": "type description"
		 }
 	  }
	}
}

A WebComponent specifies all its properties under the model, all the events under handlers and api has the javascript api the webcomponent has that the server can call.

Types are defining internal types that are used by this webcomponent for one or more of its properties.  (for example a tabpanel component has a tab type that describes one tab inside the tabpanel). They have the same support as under model:{}, there is no support for api or handlers on those types again because they are just container objects that push data to the webcomponent from the server.

Besides that the type description can be a simple (property) types like:

 

The function description in the handlers section can be just "function" or a more complex type describing the arguments and return type

"functionName": {
        "returns": "string",
        "parameters":[
                                {
                                  "name":"start",
                                  "type":"int"
                                } 

                               { 

                                  "name":"end",
                                  "type":"int"
                                } 
                              ]
}

The  signature description should also be like the complex function type, describing the arguments and return type 

"functionName": {
        "returns": "string",
        "parameters":[
                                { 
                                  "name":"start",
                                  "type":"int"
                                } 

                               { 

                                  "name":"end",
                                  "type":"int"
                                } 
                              ]
}

Example

As an example we could have a Tab Panel that has a definition (this example does not contain the entire Tab Panel spec) like this

{
	"name": "svy-tabpanel",
	"displayName": "Tab Panel",
	"icon": "servoydefault/tabpanel/tabs.gif",
	"definition": "servoydefault/tabpanel/tabpanel.js",
	"serverscript": "servoydefault/tabpanel/tabpanel_server.js",
	"libraries": ["servoydefault/tabpanel/accordionpanel.css"],
	"model":
	{
	        "background" : "color", 
	        "borderType" : "border", 
	        "enabled" : {"type":"boolean", "default":true}, 
	        "fontType" : "font", 
	        "foreground" : "color", 
	        "horizontalAlignment" : {"type" :"int", "scope" :"design", "values" :[{"LEFT":2}, {"CENTER":0},{"RIGHT":4}],"default" : -1}, 
	        "location" : "point", 
	        "readOnly" : "boolean", 
	        "selectedTabColor" : "color", 
	        "size" : {"type" :"dimension",  "default" : {"width":300, "height":300}}, 
	        "styleClass" : { "type" :"styleclass", "scope" :"design", "values" :[]}, 
	        "tabIndex" : "int", 
	        "tabOrientation" : {"type" :"int", "scope" :"design", "values" :[{"default" :0}, {"TOP":1}, {"HIDE":-1}]}, 
	        "tabSeq" : {"type" :"tabseq", "scope" :"design"}, 
	        "tabs" : "tab[]", 
	        "transparent" : "boolean", 
	        "visible" : {"type":"boolean", "default":true} 
	},
	"handlers":
	{
	        "onChangeMethodID" : "function", 
	        "onTabChangeMethodID" : "function" 
	},
	"api":
	{
	        "addTab": {
	            "returns": "boolean",
				"parameters":[
								{                                                                 
 								"name":"form/formname",
								"type":"object []"
			                	},
             					{                                                                 
 								"name":"name",
								"type":"object",
			            		"optional":"true"
			            		}        
							 ]
	        },
	        "getMaxTabIndex": {
	            "returns": "int"
	        }
	},
	"types": {
	  "tab": {
	  	"model": {
	  		"name": "string",
	  		"containsFormId": "form",
	  		"text": "tagstring",
	  		"relationName": "relation",
	  		"active": "boolean",
	  		"foreground": "color",
	  		"disabled": "boolean",
	  		"imageMediaID": "string",
	  		"mnemonic": "string"
	  	}
	  }
	}
	 
}