Building Config Driven UI Platforms
Parminder Singh
Lead UI Engineer @ Swiggy
Agenda
-
What is Config Driven Development (CDD)?
-
Example Case Study - Requirements Analysis
-
Mason UI Config JSON Walkthrough
-
Building Config Renderer in React 16.9.0 using Hooks
-
Live Exercise/Demo
-
Questions
Config Driven Development (CDD)?
-
Extending notion of configuration files to execute code
-
Removes Code Duplication
-
Write various rules to execute business logic
-
Reduces development cost and effort
-
Build in generic manner and extend for specific use cases
-
Separation of concerns
-
Removes dependency for Deployment
Case Study
-
User interaction
-
State Management
-
Inter-dependencies amongst components
-
Fetching remote data sources on various events
-
Handling user input validations
Requirements
Web Components
@mollycule/mason
Installation
npm i @mollycule/mason -S
yarn add @mollycule/mason
const LoginFormPage = () => {
const loginFormRenderer = new ReactConfigRenderer(
config,
new Map([
["TEXTFIELD", TextField],
["BUTTON", Button],
["BUTTON_PANEL", ButtonPanel]
]),
{
initialValues: new Map([["email", "paramsinghvc@swiggy.com"]]),
}
);
const LoginForm = loginFormRenderer.render();
return (
<section>
<LoginForm />
</section>
);
};
export default LoginFormPage;
Usage
@mollycule/mason
Node Configuration
{
"id": "<Unique Component Id>",
"type": "<Component Type>",
"meta": {
"disabled": false,
"maxLength": 50,
"placeholder": "Search here",
},
"show": true,
"validations": [],
"events": {},
"data": {},
"style": {
"display": "grid"
},
"children": [...]
}
@mollycule/mason
{
"page": "FORM",
"config": [
{
"id": "email",
"type": "TEXTFIELD",
"meta": {
"placeholder": "Enter your email",
"type": "email",
"value": "",
"autoComplete": "off"
},
"validations": [
{
"type": "REQUIRED"
},
{
"type": "LENGTH",
"meta": {
"min": 3,
"max": 50
}
},
{
"type": "REGEX",
"meta": {
"pattern": "^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$"
}
}
],
"events": {
"onChange": [
{
"type": "SET_VALUE"
}
]
},
"style": {
"marginBottom": 10
}
},
{
"id": "password",
"type": "TEXTFIELD",
"meta": {
"value": "Password@123",
"type": "password",
"placeholder": "Enter your password"
},
"events": {
"onChange": {
"type": "SET_VALUE"
}
},
"style": {
"marginBottom": 10
},
"validations": [
{
"type": "REGEX",
"meta": {
"pattern": "^(?=.*\\d)(?=.*[!@#$%^&*])(?=.*[a-z])(?=.*[A-Z]).{8,}$"
}
}
]
}
]
}
Event Handling
{
"events": {
"onChange": [
{
"type": "SET_VALUE"
},
{
"type": "AJAX_CALL",
"meta": {
"endpoint": "https://api.edamam.com/search",
"queryParams": {
"q": "<%SELF%>",
"app_id": "<APP_ID>"
},
"dataProcessor": "recipeDataSourceProcessor",
"fieldId": "recipesListGroup"
},
"when": {
"operator": "=",
"leftOperand": "<%secondSearchInput%>",
"rightOperand": "",
"type": "ATOMIC"
}
}
],
"onFocus": {
"type": "SET_VALUE",
"meta": {
"value": [],
"fieldId": "<fieldIdToSetValueFor>"
}
},
"onClick": [
{
"type": "SET_DATASOURCE",
"meta": {
"data": [],
"fieldId": "<fieldIdToSetDataSourceFor>"
}
},
{
"type": "CUSTOM",
"meta": {
"name": "<customFunctionNameHere>"
}
}
]
}
}
Validations
{
"type": "REQUIRED"
},
{
"type": "REGEX",
"meta": {
"pattern": "^(?=.*\\d)(?=.*[!@#$%^&*])(?=.*[a-z])(?=.*[A-Z]).{8,}$"
}
},
{
"type": "RANGE",
"meta": {
"min": 3,
"max": 10
}
},
{
"type": "LENGTH",
"meta": {
"min": 3,
"max": 10
}
},
{
"type": "JSON"
},
{
"type": "CUSTOM",
"meta": {
"name": "myCustomValidator"
}
}
Custom Validator
new ReactConfigRenderer(
config,
new Map([...]),
{
validators: {
myCustomEmailValidator(value: string) {
return !value.includes("swiggy") ? "Not a valid swiggy email" : undefined;
}
}
}
);
Conditional Logic
"show": {
"type": "ATOMIC",
"operator": "!=",
"leftOperand": "<%statesDropdown%>",
"rightOperand": "[]"
}
"disabled": {
"type": "COMPOUND",
"operator": "&&",
"leftOperand": {
"type": "ATOMIC",
"operator": "!=",
"leftOperand": "<%statesDropdown%>",
"rightOperand": "[]"
},
"rightOperand": {
"type": "ATOMIC",
"operator": "!=",
"leftOperand": "<%citiesDropdown%>",
"rightOperand": "[]"
}
}
Atomic
Compound
Exersice
Questions?
@paramsingh_66174
Thank You
Building Config Driven UI Platforms
By Param Singh
Building Config Driven UI Platforms
- 1,694