Bring Your Own (BYO) 7.22 Implementation Examples
Overview
The Bring Your Own (BYO) 7.22 implementation examples page contains a list of arguments for custom elements. Use this list as a base for building your own components using our BYO Component SDK guide.
The Bring Your Own framework is intended for developers who have a strong understanding of the Unqork Designer Platform and JavaScript JavaScript is an object-oriented computer programming language. It is most-commonly used for interactive effects in the browser..
This example is for Creators using the 7.22 Unqork Designer Platform release. For environments using the 7.24 release, view our BYO 7.24 Implementation Examples.
Simple UI
args Example
arg type | Object Type | Description |
---|---|---|
input |
string componentKey |
Subscribe to external textfield value, based on which updates occur in the heading text. |
output |
string componentKey |
On button-click, updates the external component value. |
Implementation
export class SimpleUI extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
}
/**
* This is the only method that is required from "unqork" in order to pass the api and config.
* The developer does not need this is in order to make a basic web component.
* @param {*} initialConfig
* @param {*} api
*/
initialize(initialConfig, api) {
this.config = initialConfig
this.api = api
this.setExternalComponentValue('This was set when component was initialized')
this.subscribeToValueChange()
this.subscribeToValidationChange()
this.subscribeToInputData()
}
/**
* This is the web component lifecycle method,
* it's recommended for initializing view and events.
*/
connectedCallback() {
this.initialView()
this.setupEvents()
}
disconnectedCallback() {
this.setExternalComponentValue('This was set when component was destroyed')
}
/**
* Subscribe to this component value state change,
* its only needed if the component will have updated values set using set_property
*/
subscribeToValueChange = () => {
this.api.state.state$('value').subscribe((value) => {
if (value) this.shadowRoot.getElementById('custom-input').value = value
})
}
/**
* Subscribe to this component to validate state change and render errors
*/
subscribeToValidationChange = () => {
this.api.state.state$('validation').subscribe((validation) => {
const errors = this.shadowRoot.getElementById('errors')
if (!validation) return
if (validation.result.isValid) errors.innerHTML = ''
else errors.innerHTML = validation.result?.errors?.map((e) => `<div>${e.message}</div>`)
})
}
/**
* Subscribe to the external component values
*/
subscribeToInputData = () => {
const inputRefKey = this.config.args.input
const setHeading = (c) => {
const heading = this.shadowRoot.getElementById('heading')
heading.innerHTML = c.value ? `Hello, ${c.value}!` : ''
}
if (inputRefKey) console.warn('data input not defined')
setHeading(this.api.state.resolveByKey(inputRefKey))
this.api.state.resolveByKey$(inputRefKey).subscribe(setHeading)
}
/**
* Set validation for a state
* @param {*} isValid
* @param {*} errors
*/
setValidation = (isValid, errors) => {
this.api.state.set((state) => {
return merge(state, 'validation.result', {
isValid,
errors,
})
})
}
/**
* For the given component key, update its value
* Avoid changing every component property and expect it to work
* it depends on the component implementation if the state update will be respected
*
* @param {*} key
* @param {*} value
*/
setExternalComponentValue(value) {
this.api.state.updateExternalComponentState(this.config.args.output, { value })
}
/**
* Render initial DOM structure
*/
initialView() {
this.shadowRoot.innerHTML = `
<h1 id="heading"></h1>
<button id="fireEventBtn">Fire Event</button>
<button id="updateOutputBtn">Set output</button>
<button id="setInvalidBtn">Make component invalid</button>
<button id="setValidBtn">Make component valid</button>
</br>
<input type="text" id="custom-input"/>
<div id="errors"></div>
`
}
/**
* Bind events
*/
setupEvents() {
const fireEventBtn = this.shadowRoot.getElementById('fireEventBtn')
const updateOutputBtn = this.shadowRoot.getElementById('updateOutputBtn')
const setInvalidBtn = this.shadowRoot.getElementById('setInvalidBtn')
const validBtn = this.shadowRoot.getElementById('setValidBtn')
const input = this.shadowRoot.getElementById('custom-input')
// Add an 'onclick' event listener
fireEventBtn.onclick = () => this.api.events.emit({ name: 'customEvent' })
updateOutputBtn.onclick = () => this.setExternalComponentValue('This was set from an output')
setInvalidBtn.onclick = () => this.setValidation(false, [{ type: 'customError', message: 'errorMessage' }])
validBtn.onclick = () => this.setValidation(true, [])
input.addEventListener('keyup', (e) => this.api.state.set({ value: e.target.value }))
}
}
export default SimpleUI
Ag Grid
args
arg type | Object Type | Description |
---|---|---|
input |
string componentKey |
Subscribe to the external component with the component definition array An array is a type of object that stores one or more data types. Data types supported in arrays include numbers, strings, and objects.. |
output |
string componentKey |
Subscribe to the external component with the data the grid should display. |
Implementation Example
// << Import/Insert the AgGrid lib here.>>
// << For readability purposes it has been removed.>>
export class AgGrid extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.gridOptions = {
columnDefs: [],
rowData: [],
}
}
initialize(initialConfig, api) {
this.config = initialConfig
this.api = api
this.renderGrid(this.shadowRoot, this.gridOptions)
this.subscribeColumnDefs()
this.subscribeData()
}
subscribeColumnDefs() {
this.api.state.resolveByKey$(this.config.args.columnDefs).subscribe((columnDefs) => {
this.gridOptions = {
rowData: this.gridOptions.rowData,
columnDefs: columnDefs.value || [],
}
this.updateGrid(this.gridOptions)
})
}
subscribeData() {
this.api.state.resolveByKey$(this.config.args.value).subscribe((rowData) => {
this.gridOptions = {
rowData: rowData.value || [],
columnDefs: this.gridOptions.columnDefs,
}
this.updateGrid(this.gridOptions)
})
}
updateGrid(gridOptions) {
console.log('Updating AG Grid', gridOptions)
this.gridApi.updateGridOptions(gridOptions)
}
async renderGrid(document, gridOptions) {
console.log('Rendering AG Grid component', gridOptions)
document.innerHTML = this.view()
this.gridEl = document.querySelector('#myGrid')
this.gridApi = agGrid.createGrid(this.gridEl, gridOptions)
console.log('Created AG Grid', {
document,
gridOptions,
gridEl: this.gridEl,
gridApi: this.gridApi,
})
}
view() {
return `
<div id="myGrid" style="height: 500px"></div>
`
}
}
export default AgGrid
Resources
Bring Your Own (BYO) Framework Landing Page
Find all the resources needed to build your own components here.
Introduction to the Bring Your Own (BYO) Framework
Create a BYO Package
Understanding the manifest.json File
Learn about the file's specification, component and event definitions.
Understanding the BYO Runtime Engine API
Discover the interface between your custom BYO components and the Unqork platform.
Custom Component SDK
Extend component functionality in the Unqork Designer Platform.
Custom Component
Understand the state, interface, and events of a custom component.
BYO 7.24 Implementation Examples
Discover examples of component implementation using the 7.24 Unqork Designer Platform.
Host External Assets Using a CDN (Content Delivery Network) Setup
Learn about setting up Express roles and managing permissions.
BYO Best Practices
Learn about best practices for implementing and using BYO assets.