Example Progress Bar
Let's see a more interesting example. Now we are going to build a component that renders a progress bar.
import * as React from "react";
import { Model, _ } from "@flowable/forms";
export function ProgressBar(props: Model.Props) {
const { config } = props;
const max = config?.extraSettings?.max || 100;
const val = ((config?.value || 0) * 100) / max;
return (
<div id={config.id} className="flw__component">
<div
style={{
width: "100%",
height: "39px",
backgroundColor: "#dadada",
borderRadius: "2px",
}}
>
<div
style={{
width: `${val}%`,
height: "100%",
backgroundColor: val > 66 ? "#85cc00" : val > 33 ? "#ffbf00" : "#ff2e00",
borderRadius: "2px",
transition: "all .2s ease-out",
}}
/>
</div>
</div>
);
}
This component takes the value it's bound to (config.value) and displays it as the width of the progress bar. It also takes an optional attribute of the component configuration (extraSettings.max) and uses it as the width of the maximum value of the progress.
A possible configuration for this component could be:
{
"type": "progressBar",
"value": "{{progress}}",
"extraSettings": {
"max": 5000
}
}
When Flowable Forms finds that configuration inside a form definition it will $resolve it and then it will instantiate ProgressBar and pass the resolved configuration in the config prop.
Resolving a component means to convert all the expressions into actual values and add some additional attributes to ease the implementation of components. For example the previous configuration could be $resolved into:
{
"type": "progressBar",
"value": 10,
"extraSettings": {
"max": 5000
},
"$original": {
"type": "progressBar",
"value": "{{progress}}",
"extraSettings": {
"max": 5000
},
},
"$scope": {
"progress": 10
},
"$errors": [],
"$computedPath": ".extraSettings.layoutDefinition.rows.0.cols.0"
}
As you can see the value attribute now is not {{progress}}
anymore and it has been resolved to 10
, the current value of the variable progress.
The unresolved configuration can be checked inside the $original attribute, $scope contains the scope of this component, $errors contains the failed validations and $computedPath contains the path of this component inside the tree of resolved form.
These attributes starting with $ can be ignored in most of the components.