Experimental
The context in which the UI is rendered
The JSX element representing the UI to be shown
An object with state property that holds the current UI values and property button that holds the value of the clicked button that resolved the showUI promise
bubble
, modal
, shield
, and splitView
.showUI
can be resolved by using button
component with resolve: true
property or by using navigationBar
component with buttons
property. One of them must be present to resolve the showUI promise.group
.vertical
and horizontal
functions can be used.progressItem
component. Make sure showUI is called with void and not awaited.Usage with various elements
const result = await showUI(
ctx,
bubble([
headerBar({title: 'Modular UI form'}),
group([
text({
// TODO: change so that other options are optional and content is a second or only argument
text: async (data) =>
'**First name:** ' +
data.firstName +
'\n **Country:** ' +
data.country +
'\n **Hobby:** ' +
data.hobbies +
'\n **Food:** ' +
data.food,
}),
input({
name: 'firstName',
label: 'First name',
defaultValue: 'Mark',
}),
fileUpload({
name: 'upload-file',
fileUploadTitle: 'Upload Files',
uploadButton: 'Upload',
text: 'Please select file to upload.',
error: 'You can upload up to 3 files only.',
maxFileLimit: 3,
minFileLimit: 1,
loadingText: 'Uploading...',
validate: async (file:DroppedFile) => {
const isValid = false // Apply your validation logic here
const message = isValid ? '' : 'File is not valid'
return {
isValid,
message,
processedFile: file
};
},
allowedTypes: {
types: ['image/*', 'application/pdf'],
message: 'File type must be an image or a PDF',
},
maxFileSize: {
size: 5 * 1024 * 1024, // 5MB
message: 'File size must be less than 5MB',
},
}),
select({
name: 'country',
label: 'Country',
items: [
{value: 'us', label: 'United States'},
{value: 'de', label: 'Germany'},
{value: 'fr', label: 'France'},
],
}),
checkboxList({
name: 'hobbies',
label: 'Hobbies',
items: [
{value: 'reading', label: 'Reading'},
{value: 'traveling', label: 'Traveling'},
{value: 'cooking', label: 'Cooking'},
],
}),
radioList({
name: 'food',
label: 'food',
items: async (state) =>
state.country === 'us'
? [
{value: 'burger', label: 'Burger'},
{value: 'fries', label: 'Fries'},
]
: [
{value: 'pasta', label: 'Pasta'},
{value: 'pizza', label: 'Pizza'},
{value: 'salad', label: 'Salad'},
],
}),
statuses({
statuses: [
{ status: 'success', text: 'Data fetched successfully.' },
{ status: 'warning', text: 'Data filtered successfully.' },
{ status: 'error', text: 'Data filtered successfully.' },
],
}),
button({
text: 'Submit',
value: 'submit',
resolve: true, // to resolve the showUI promise
updateState: async (state, value) => { // buttons can also update state
const count = state.count || 0;
return {count: count + 1};
},
}),
spinner({
title: 'Loading...',
description: 'Please wait while we load the data.',
}),
]),
]),
);
Usage to show a spinner
void showUI(ctx,
bubble([
group([
progressItem({
status: 'running',
title: 'Loading...',
description: 'Please wait while we load the data.',
}),
]),
]),
);
Usage with text and navigationBar that can be used to display a message to user
const result = await showUI(ctx,
bubble([
headerBar({title: 'Modular UI Message Component'}),
group([
text({text: 'Welcome to the Modular UI world!'}),
]),
navigationBar({
buttons: [
{text: 'Proceed', value: 'ok'},
],
}),
]),
);
@example
Usage with button inside group
```tsx
const result = await showUI(ctx,
bubble([
headerBar({title: 'Modular UI with button inside group'}),
group([
text({text: 'Please click the button below to submit the form.'}),
button({
text: 'Submit',
value: 'submit',
resolve: true, // to resolve the showUI promise
updateState: async (state, value) => { // buttons can also update state
const count = state.count || 0;
return {count: count + 1};
},
}),
]),
]),
);
Usage with form elements and navigationBar
const result = await showUI(ctx,
bubble([
headerBar({title: 'Modular UI Form Component'}),
group([
input({name: 'name', label: 'Name'}),
input({name: 'email', label: 'Email'}),
input({name: 'password', label: 'Password'}),
]),
navigationBar({
buttons: [
{text: 'Proceed', value: 'ok'},
],
}),
]),
);
// result returned value: {button:"ok",state:{name:"John",email:"john@example.com",password:"supersecret"}}
@example
Usage with file upload
const result = await showUI(ctx,
bubble([
headerBar({title: 'Modular UI File Upload Component'}),
group([
fileUpload({
name: 'upload-file',
fileUploadTitle: 'Upload Files',
uploadButton: 'Upload',
text: 'Please select file to upload.',
error: 'You can upload up to 3 files only.',
maxFileLimit: 3,
minFileLimit: 1,
loadingText: 'Uploading...',
validate: async (file:DroppedFile) => {
const isValid = false // Apply your validation logic here
const message = isValid ? '' : 'File is not valid'
return {
isValid,
message,
processedFile: file
};
},
allowedTypes: {
types: ['image/*', 'application/pdf'],
message: 'File type must be an image or a PDF',
},
maxFileSize: {
size: 5 * 1024 * 1024, // 5MB
message: 'File size must be less than 5MB',
},
}),
]),
navigationBar({
buttons: [
{text: 'Proceed', value: 'ok'},
],
}),
]),
);
Shows a dynamically generated UI - !!!POC version, expect changes