components are units of functionality that are bundled together as a single unit, typically as a javascript
module. Components are things like charts or tables, although they do not necessarily require
a visual aspect.
Component Requirements
In order to design a component, you must write your code to comply with the component specification.
The primary requirement for a component is that it is encoded in javascript module as below.
export function constructor(config, options){
this.config = config;
}
The module should contain an exported function named "constructor" which is an object constructor
that takes a config as a parameter. The config should be set on the object itself as above.
The options is an additional dictionary passed in by the platform that specifies additional options
on the component. For simple components this can be ignored.
Component Config
The component config contains information needed by the platform to appropriately run the component.
In addition, it should save whatever details are required by the component to run itself properly.
That is, you should saved information about the state of teh component in the config. However,
because the platform needs to save information in the config as well, there are only two properties
available for components to save data in:
attributes
body
You are free to structure the data any way you wish, although typically these properties should be set as
dictionaries that you can save information into.
The component script is provided in the "script" property of the config. This should be the URL
of the javascript library (see above) that implements the component. When the component is added to
the workspace or blog, the script is loaded and then an instance of teh component is instantiated by
calling new on the "constructor" method, passing the config into the constructor.
If the component is a visual component that may have children elements (i.e. elements that can be inserted into
them) then the config should have a property named "children" that is set to an empty array. This array will
be populated with the configs of any child component inserted into the component itself.
Adding a component to a blog or a workspace is easy, just by calling the $page.add method.
await $page.add(config);
Sample Component
The following is a simple example of a fully functional component. Assume the following code is saved at the
URL '/server/sample.js'
export function constructor(config, options){
this.config = config;
alert('hello');
}
Then the following code adds the component
$page.add({
script:'/server/sample.js'
})
This component doesnt do anything other than create an alert dialog on instantiation. However, it is a fully
compliant component.
Lifecycle Methods
The sample component, while compliant, is not very functional. In order to provide additional functionality, the platform
will call a set of methods on the component in order to manage it through its lifecycle. We refer to these methods as
lifecycle methods. Lifecyle methods are called using the
dependency injection framework.
$libraries : for components that are dependent on libraries (not other modules) that
need to be loaded before the component can function, you can implement a method named "$libraries"
that returns an array of urls that need to be loaded.
$copy : $copy is a method that is called when a component is copied by the
user, typically by click ctrl-c. The method should return a copy of the
config that should be placed in the clipboard. This is useful if the
copied config should be different from the config of the ctrl.
if this method is not present, the config that is copied to the clipboard
matches the config of the component in the blog or workspace that is being
copied.
$css :
$css is similar to $libraries above. It returns any urls that represent style sheets that need to be loaded
$html :
For components that need to insert html into the page, the $html method needs to be implemented.
It returns html that will be inserted by the platform. Typically, you will need to use the
$id service to create an id for the html. The following is a typical example
Usually, it is not required to return much more html than a simple div, as the $process method, given below
is called right after the html is inserted (assuming that is present on the component).
$process :
The $process method is called right after a components html has been inserted. If the component has no html,
the $process method is still called. For components that retrieve data or some other non-visual action, the $process
method is the primary method that implements the components functionality.
For components that have more complex html, the process method can be used to insert html into its html
container. In such a case, the $process method should use the $id service to get the id of the inserted
html.
$remove :
The $remove method is called when the component is removed from the page. This gives the component
a chance to clean itself up by removing its html and any data it may have place ont the data bus.
$imports :
When a component uses data that is provided by another component, such as a chart displaying data provided
by a data component, the component gets acces to that data through the
data bus. If a component is dependent on data on the bus, it should
implement the $imports method. This method returns an array of data names that it is dependent on.
This enables the platform to track dependencies between components.
$exports :
If a component puts data on the data bus, it should implement the $exports method, which should
return an array of data names of teh datasets it places on the data bus.
$update :
Whenever data on the data bus changes, the platform calls $imports on all components. For any component
that imports the data that has changed on the bus, the $update method is called.
$select :
The $select method is called when the component is selected by the user in the page. This gives the component
the chance to highlight itself in the page as well as display any controls to edit the component. It should
have an argument named "selected" that is passed to it. When the $select is not present, the component is
not selectable.
$inline :
The $inline method is used to control the buttons and controls that appear when a component is selected. (if the component
has such controls). It should be passed a boolean argument named "open" that indicates whether to open or close the controls.
In general, a component should open these controls whenever its $select method is called with selected set to true. However,
ocassionally, the framework needs to hide the controls, so this method is made available for that purpose.
Component Effects
Adding a component to a blog or a workspace is easy, just by calling the $page.add method.
let config = $config(id);
if (!('wrappers' in config)) config.wrappers = [];
let params = {
name: 'bounce',
script: '/lib/effects/v1.0.0/bounce.js',
};
config.wrappers.push(params);
When a parameter such as the above is added to a configs wrappers, then when the component is instantiated, the
script listed in the parameter is loaded and a function named "wrap" is called in the loaded script. The following
is and example wrap function.
export function wrap(params, ctrl){
}
The parameter in the wrappers list is passed to the wrap function along with the instantiated component. The wrap
function can alter the component in order to achieve its functionality. The primary way to do this is to replace
the $process function on the component