B4J Library [BANanoVueMaterial]: The first complete opensource VueJS UX based framework for BANano


As of 02 FEB 2021, this project is is no longer maintained as it has given birth to BVAD3.

This project was a joy to create, however like everything that has a start and an end, its time to move on and evolve. BVAD3 is faster, more simpler to implement and takes advantage of the Abstract Designer use.

Subscribe to Telegram Channel

[BANanoVuetifyAD] Vuetify WebSites & WebApps with BANano for Dummies



UPDATE 24 October 2020: The recommended methodology to create BANanoVuetify WebApp is being discussed here:
MealPrep. This covers most of what VueJS + Vuetify is all about in terms of the internals.

Whilst you can use the designer to create your UX, you need to separate your concerns when creating the app just like its done on the MealPrep by using components and routers for the pages.



BANanoVuetifyAD - Prelease Playlist on Youtube
BANanoVueMaterial (Vuetify) Playlist on Youtube

2020-05-20 Update: Important Update

BANanoVueMaterial Designer Usage - Mock.Compile.Publish

BANanoVueMaterialCore (pure vuetify without extensions)

Exploring Components & Router Basics

How to ask questions, request help, report bugs and request enhancements + Telegram Channel

Thanks to everyone who has been playing with this and highlighting issues and requesting features. You are stars!

*** IMPORTANT: Migrating to the new version

Word. Moving from VueMaterial to Vuetify was inevitable and whilst both are Vue Material based frameworks, Vuetify has more strengths. If if was going to be possible, we would not be having a migration guide, however things changed and enhancements happened and some code rewrites took place. When doing the transition from the VueMaterial to Vuetify codebases, we tried to make the code transition to be as smooth as possible, thus our migration guide is as small as possible. We did not want to dictate how to use the lib, so we removed some things that were hard coded and fixed. This was specific to the side drawer. To test the migration, the old examples were converted to new examples (see below) and all of them work.

BANanoVueMaterial is complete open source, so this means you can use it to your hearts content and adjust it and make it your own. If you enhance, send us word, we will merge. Make the code simple and comment it as much as you can. I cannot over-emphasize that Vuetify is LARGE, so check their website on how components are created and used to learn stuff. Do enjoy. TheMash. #IAmLovingThis

BANanoVuetify (recommended for new projects & migration notes attached)

You can track our progress from here. All the components that we got from VueMaterial exists in Vuetify and more!!!

  • Copy all the files in the 1. External Libraries folder to your B4J external libraries folder
  • If you want to explore the BANanoVuetify source code, open and run the project in 2. Library
  • If you want to explore all the components in this version, open and run the project in 3. Demo
  • You can also explore other specific examples from the 4. Examples folder
Live Preview

Tutorials (New)


NB: Download and Import the Project Components files for the Expense Tracker here.

1. Expense Tracker with BANanoSQL

Expense Tracker Part 1
Expense Tracker Part 2
Expense Tracker Part 3
Expense Tracker Part 4
Preparations for Part 5
Expense Tracker Part 5.1
Expense Tracker Part 5.2

2. Expense Tracker with SQLite (you need to understand all of 1. Expense Tracker with BANanoSQL first!)

Making your app use SQLite as a backend
Mock.Compile.Publish Expense Tracker with SQLite as BackEnd Full Implementation

3. Expenses Tracker with MSSQL (you need to understand all of 1. & 2. above first!)

Mock.Compile.Publish Expense Tracker with MSSQL as BackEnd

4. Expense Tracker with MySQL (you need to understand all of 1. - 3. above first)

Mock.Compile.Publish Expense Tracker with MySQL as BackEnd

NEW NEW NEW!!!! Handling Events

Developing a grid with the Designer
Developing forms with the Designer
Designing text field controls with the Designer
Designing text area controls with the Designer
Designing password controls with the Designer
Designing images with the Designer
Designing file input with the Designer
Designing buttons with the Designer
Designing checkboxes with the Designer
Designing switches with the Designer
Designing icons with Designer
Designing labels with Designer
Designing sliders with the Designer
Designing select, combo and autocomplete with the Designer
Designing radio boxes with the Designer
Designing date & time pickers with the Designer (NB: functionality works on your app)
Designing a parallax with the Designer
Designing a container with the Designer
Designing the appbar, toolbars and systembar with the Designer - Part 1
Designing the appbar, toolbars and systembar with the Designer - Part 2
Drag n Drop Menu - Part 1
Drag n Drop Menu - Part 2
Drag n Drop Carousel
Drag n Drop Dialog
Drag n Drop Rating
Drag n Drop SpeedDial
DataTable multi selects
Invisible File Selector
DataTable GetItemKeys
Drag n Drop Chips
Drag n Drop Badges
Drag n Drop Avatars
Exporting Component Schemas (Multi Development Mode)
Importing Component Schemas (Multi Development Mode)
Drag n Drop Lists
Drag n Drop Tabs
Drag n Drop Stepper
Drag n Drop ExpansionPanels (Accordion)
Drag n Drop Page
Setting Project Properties
Reading Text files (without upload to server)
Reading Excel files (without upload to server)

Reporting (New)

Excel Client Side Reporting with OXML

Example Projects

Hello World
Navigation (1 or more pages using v-show directive)
Login Screen
User Registration Screen
Expenses.Show - MySQL+PHP+ChartKick CRUD
Form Utilities - BANanoSQL CRUD
Calculations - using watch directives

IMPORTANT: Asking Questions about BANanoVueMaterial

1. Please do not ask questions on this thread as this is about updates and new developments about BANanoVueMaterial.
2. When asking a question, please use the B4J Forum and prefix your question with [BANanoVueMaterial] Your Question
3. As the author of this lib, I would recommend that in the content of your question you also address it to myself with @Mashiane (this will also help me find and attend to your questions faster as it will show in my personal notifications)

Related Content

BANanoVue - a now updated CORE of BANanoVueMaterial
BANanoWired - a mockup framework build on BANanoVue (WIP)
BANanoPDFDesign - a creation based on BANanoVueMaterial for PDF reporting (WIP)
BANanoVMDesign - this intends to support BANanoVueMaterial design philosophy. (WIP)

Have fun and enjoy!

PS: BANanoVueMaterial uses an updated version of the BANanoPostProcessor library done by Kiffi.
Last edited:


Licensed User
Longtime User
Upcoming Updates: Radio Group

An additional function to allow radio groups to be loaded from a database like structure is added, this is how it works.


Dim continents As List
    continents.add(CreateMap("id":"africa", "text":"Africa"))
    continents.add(CreateMap("id":"america", "text":"America"))
    continents.add(CreateMap("id":"newzeleand", "text":"New Zealand"))
    vm.setstatesingle("continents", continents)

    Dim rg2 As VMRadioGroup = vm.CreateRadioGroup("rg2", "DataSource", Me).SetVModel("ds")
    rg2.SetDataSource("continents", "id", "text")
    rg2.AddToContainer(cont, 2, 1)

We assume that the continents is sourced from a db. We use .SetDataSource for the radio group..

We can also trap the change event of the rado group, for example here, we show the value that is selected.

Sub rg2_change(value As Object)
End Sub


Licensed User
Longtime User
Working with Watches (not the one you wear -- lol)


Here we want to be able to calculate the total value each time the quantity and the rate changes. VueJS has a nifty tool to do this, a concept called watches. This helps one detect changes on the v-model of an element. So what we want to do is each time a qty and rate changes the total is calculated.

We achieve this via a callback. We add components to our page and assign vmodels to them.
We then add watches for these vmodel states so that whenever the are changes, stuff happens.

Dim txtQty As VMInput = vm.CreateInput("txtqty", Me).SetLabel("Quantity").SetVModel("qty").SetTypeNumber(True)
    Dim txtRate As VMInput = vm.CreateInput("txtrate", Me).SetLabel("Rate").SetVModel("rate").SetTypeNumber(True)
    Dim txtTotal As VMInput = vm.CreateInput("txttotal", Me).SetLabel("Total").SetVModel("total").SetTypeNumber(True)

IMPORTANT: Set the vmodels

  1. The vmodel for quantity is "qty"
  2. The vmodel for rate is "rate" and
  3. The vmodel for total is "total"
So we define the callback to call when ever a change happens in those 2 vmodels( qty and rate)

'set computed for the total
Sub ComputeTotal
    'get the qty
    Dim iQty As Int = vm.getstate("qty",0)
    'get the rate
    Dim iRate As Int = vm.getstate("rate", 0)
    'calculate total
    Dim iTot As Double = BANano.parseint(iQty) * BANano.parseFloat(iRate)
    'format the amout
    iTot = Round(iTot, 2)
    'save the total
    vm.SetStateSingle("total", iTot)
End Sub

We then when building our app, tell our app that we need to watch these states.

vm.SetWatch("qty", True, False, Me, "computetotal")
    'we want t watch for changes in rate
    vm.SetWatch("rate", True, False, Me, "computetotal")

So each time the 2 states changes, our total is calculated.! Walla!


  • Calculations.zip
    17.8 KB · Views: 264
Last edited:


Licensed User
Longtime User
Its is with pleasure to release BVM 2.12 (GitHub link on first post)

1. RadioGroup loading from database table structure
2. AutoComplete loading from a database table structure and .GetValue and .SetValue methods for key access in key value fields.
3. EasyHint for tour generation
4. New Drawer section for Concepts added e.g. explaining the watch methodology.
5. Devices
6. Google Map
7. ChartKick
8. File Uploading

Known Issues: A lag when typing fast on input boxes.

Bug fixes



Licensed User
Longtime User
IMPORTANT: Time to grow: Migrating BVM from VueMaterial to Vuetify aka BANanoVueMaterial 3

BVM2 is still functional and usable


A decision needed to be made, and needed to be made quickly. So far 3 successful projects have been delivered with this library from my side for different clients and one is just being finalized. Based on the comparison table above, the move was inevitable. One of the greatest pros to this move is "Long term support" for Vuetify and the other benefits.

Win 1 - Removing Unnecessary plugins

One of the things I needed to do to make BVM 2 work for the way I needed it to be was to add plugins. The pain with this was using the Gijgo table as the VueMaterial table functionality was incomplete. I love the gijgo table, but then again, the pro with Vuetify is that it already comes with a built in table. So I don't need the extra library. This is also inclusive of the RangeSlider plugin as the upcoming one is just as potent.

Win 2 - Code compatibility

After playing around with Vuetify, I was convinced it was just a very enhanced version of VueMaterial. WRONG! The win here is that with BVM 3, I'm making the code to be almost 100% compatible, so whilst your existing app will not break, it will also have more functionality. There are so many properties per component on the Vuetify framework (to make life easy), I'm mind blown! So far we are at 90% code compatibility between BVM 2+ and BVM 3. Further tests will be done.

Win 3 - 82+ components compared to 56+

The current implementation for BVM 3 is mainly for input components and form controls. We will also delve with the table component to replace the used gijgo table for BVM 2. So the additional components will be added as and when needed. This fortunately is an automated process I have coded but pending tests to check workability.

Win 4 - build in theming

Vuetify is following the same trend that was picked up from MaterializeCSS for example, COLOR_RED, INTENSITY_ACCENT4. Most properties have a "color" property and one can easily pass an intensity. So most controls are just easy to theme as just specifying their color or their background color whilst defining them. This is a very big plus compared to BVM2.

Win 5 - flexibility

Wow, now this is the cake! With Vuetify and BVM3, only your imagination will limit you. The documentation for Vuetify is intact and a marvel and just as easy to follow.

What to expect (still in early stages)

VueMaterial & Vuetify are Material Design Frameworks based on VueJS, so the name of our lib will remain the same whilst the underlying frameworks will be changed drastically.

01. BVMButtons.png

02. BVMCombo.png

03. BVMFileInput.png

04. BVMCheckBox.png

05. BVMForm.png

06. BVMRadioGroup.png

07. BVMSelect.png

08. BVMSlider.png

09. BVMSwitch.png

10. BVMTextArea.png

11. BVMTextField.png

12. BVMImages.png

13. BVMToolbar.png

14. BVM Drawer.png

15. BVMBadges.png

16. BVMAvatar.png

17. BVMIcon.png

18. BVMGrid.png

Watch this space!

Last edited:


Licensed User
Longtime User
ChitChat: Behing the Scenes: Vuetify 2 BANano (Watch it now!)

This clip shows the process of wrapping up Vuetify or any well documented VueJS library to BANano. When well documented, one will get properties, events, slots etc. As we need to wrap this to a BANano class that we will later test to generate HTML code, we fire up something called "VueThing".

This is just a class name I decided to name. In most cases this will receive 3 things, the properties, the slots, and the events. What this does is clean up a few things and generate all the code needed to make the Component VueThing work in BANano. Most of this is .Set? methods that one can use to build their UX through setting up properties and events.

We are almost done with the wrap of all input components so that we can create DB based app. The exception is the table for display purposes, a rather crucial component.

So in simple terms...

Dim mthing As VueThing
    mthing.Initialize("VM", "EditDialog", "v-edit-dialog")
    mthing.AddProperties(Array("cancel-text", "dark", "eager", "large", "light", "persistent", _
    "return-value", "save-text", "transition"))
    mthing.AddEvents(Array("cancel", "close", "open", "save"))

1. We need to create a component class, it should be prefixed by VM.
2. The name of the componentis "EditDialog"
3. The tag of the component is "v-edit-dialog"
4. We specify the properties for the component. These methods are just shortcuts e.g. AddProperties, AddSlots, AddEvents as there are more detailed methods that also receive default and description of each property, slot, event etc.

We then use some templates to build up the B4X class. a template will look like this..

'set for
Sub SetVFor(item As String, dataSource As String) As ClassPrefix<vi>
    dataSource = dataSource.tolowercase
    item = item.tolowercase
    Dim sline As String = $"${item} in ${dataSource}"$
    SetAttrSingle("v-for", sline)
    Return Me
End Sub

This code is based on the root component VMElement where all other elements are based on and it builds the HTML template of the component we need based on .Set calls we make during development. The stuff to change in this template is ClassPrefix<vi>

'set for
Sub SetVFor(item As String, dataSource As String) As ClassPrefix<vi>
    dataSource = dataSource.tolowercase
    item = item.tolowercase
    Dim sline As String = $"${item} in ${dataSource}"$
    SetAttrSingle("v-for", sline)
    Return Me
End Sub

Why not use just 1 base element? As the methods in these components are chained, in some cases, the base elements self references, this will lead to over-runs, thus the need to define each components in its own class. At times during exploring the examples and testing that the components works as expected, it has been discovered that some components are made up of a collection of a few components to make them.



Licensed User
Longtime User
Latest Developments coming to BVM

Download BETA 2 here

With the new upgrade of BVM from VueMaterial to Vuetify well things are going surely with speed. So far we have ported over 30 components that we are able to use.

Still we are at BETA, but then again, the road has has its hurdles. Below are some stuff we have been able to do. It should be noted that wrapping a huge lib like this has its pros and cons. For now were are mainly focusing our efforts on INPUT controls. So extra components will come with time.

Search input on toolbar

23. BVM ToolbarSearch.png


24. BVMChips.png


25 BVM AutoComplete.png


26 BVMLists.png

Snackbar Configuration

27 BVMSnackBar.png


28 BVMSteppers.png


29 BVMTabs.png


30 BVMTreeView.png

NB: We are currently working tirelessly to bring the data-table to life, which will close Phase 1 of this important project. The next phase will be to run more tests with the previous version of BVM to ensure compatibility of apps so that current apps dont break much.

Thanks for showing interest in this project.

Last edited:


Licensed User
Longtime User
BETA 3 is now available, this is inclusive of the DataTable. Beta 3 is the update of the library to use Vuetify framework. Our previous BVM version used an additional library called Gijgo, this is now not necessary.

Download here

31. BVMTable.png

There are some automated processes for form design that are en route.



Licensed User
Longtime User
Input Dialog..

This demos how one can add input controls to a dialog:

NB: First ensure you call AddRows(?).AddColumns??? to build the grid where the controls will sit and then use .AddComponent(Row?, Column? ) to add each component.

32. BVM InputDialog.png

The code to create this dialog is..

Sub InputDialog As VMDialog
    Dim user As Map = CreateMap()
    vm.SetData("user", user)
    Dim diag As VMDialog = vm.CreateDialog("inputdialog", Me)
    diag.SetTitle("Input Dialog")
    Dim chkAgree As VMCheckBox = vm.CreateCheckBox("chkAgree1", Me).SetVModel("user.agree").SetLabel("I agree")
    Dim dob As VMDatePicker = vm.CreateDatePicker("dob", Me).SetVModel("user.dob").SetLabel("Date of Birth").SetForInput
    Dim fi As VMFileInput = vm.CreateFileInput("myfile", Me).SetAccept("image/*").SetLabel("File input").SetVModel("user.myfile")
    Dim rg1 As VMRadioGroup = vm.CreateRadioGroup("gender", Me).SetVModel("user.gender").SetHorizontal(True).SetLabel("Gender")
    Dim selx As VMSelect = vm.CreateSelect("code", Me).SetItems("items").SetLabel("Code").SetVModel("user.code")
    Dim age As VMSlider = vm.CreateSlider("age", Me).SetVModel("user.age").SetMin("0").SetMax("100").SetLabel("Age").SetThumbLabel("always").SetValue("46")
    Dim swt As VMSwitch = vm.CreateSwitch("notif", Me).SetLabel("Receive Notifications").SetVModel("user.notif")
    Dim txtm As VMTextArea = vm.CreateTextArea("about", Me).SetLabel("About Yourself").SetVModel("user.about")
    Dim txtfn As VMTextField = vm.CreateTextField("fn", Me).SetLabel("First Name").SetVModel("user.fn").SetHint("Enter a first name").SetPersistentHint(True).SetClearable(True).SetMaxLength(50)
    Dim ac1 As VMAutoComplete = vm.CreateAutoComplete("ln", Me).SetVModel("user.ln").Bind(":items", "items").SetLabel("Last Name")
    Dim a3 As VMAvatar = vm.CreateAvatar("dp", Me).SetImage("./assets/sponge.png", "Sponge")
    Dim tp2 As VMTimePicker = vm.CreateTimePicker("tob", Me).SetVModel("user.tob").SetLabel("Time of Birth").SetForInput
    Dim cbo1 As VMComboBox = vm.CreateComboBox("combox", Me).SetVModel("user.combo").SetItems("items").SetLabel("Select a favourate activity or create a new one")
    Dim pwd As VMTextField = vm.CreateTextField("pwd", Me).SetLabel("Password").SetPassword(True).SetName("password",False).SetVModel("user.pwd").SetHint("At least enter 8 characters.")
    diag.Container.AddComponent(1, 1, chkAgree.ToString)
    diag.Container.AddComponent(1, 2, dob.tostring)
    diag.Container.AddComponent(2, 1, fi.tostring)
    diag.Container.AddComponent(2, 2, rg1.tostring)
    diag.Container.AddComponent(3, 1, selx.tostring)
    diag.Container.AddComponent(3, 2, age.tostring)
    diag.Container.AddComponent(4, 1, swt.tostring)
    diag.Container.AddComponent(4, 2, txtm.tostring)
    diag.Container.AddComponent(5, 1, txtfn.tostring)
    diag.Container.AddComponent(5, 2, ac1.tostring)
    diag.Container.AddComponent(6, 1, a3.tostring)
    diag.Container.AddComponent(6, 2, tp2.tostring)
    diag.Container.AddComponent(7, 1, cbo1.tostring)
    diag.Container.AddComponent(7, 2, pwd.tostring)
    diag.AddCancel("btnCancelIt", "Cancel")
    diag.AddOK("btnSaveIt", "Save")
    Return diag
End Sub


Licensed User
Longtime User
BETA 4 is out...


This deals with adding controls to the parent container by specifying control position. With this method, one does not need to call .AddRows(?).AddColumns(??) first.

The grid is automatically designed from the positions and spans specified.

Example code: .SetDevicePositions & .AddControl

Sub Code
    vm = pgIndex.vm
    'create a container to hold all contents
    Dim cont As VMContainer = vm.CreateContainer(name, Me)
    'hide this container
    Dim switch As VMSwitch = vm.NewSwitch("switch1", "Radio", "Yes", "No", True, 0).SetDevicePositions(1, 1, 12, 6, 6, 6)
    cont.AddControl(switch.SwitchBox, switch.ToString)
    Dim radiogroup As VMRadioGroup = vm.NewRadioGroup("radiogroup", "Gender", "f", CreateMap("m":"Male","f":"Female"), 0).SetDevicePositions(1, 2, 12, 6, 6, 6)
    cont.AddControl(radiogroup.RadioGroup, radiogroup.ToString)
    Dim checkbox As VMCheckBox = vm.NewCheckBox("checkbox", "I concur!", "Yes", "No", True, 0).SetDevicePositions(1, 3, 12, 6, 6, 6)
    cont.AddControl(checkbox.CheckBox, checkbox.ToString)
    Dim datepicker As VMDatePicker = vm.NewDatePicker("datepicker", "Date Picker", True, "Select a Date Picker", "This date", 0).SetDevicePositions(1, 4, 12, 6, 6, 6)
    cont.AddControl(datepicker.DatePicker, datepicker.ToString)
    Dim timepicker As VMTimePicker = vm.NewTimePicker("timepicker", "Time Picker", True, "Select a time Picker", "This time", 0).SetDevicePositions(2, 1, 12, 6, 6, 6)
    cont.AddControl(timepicker.TimePicker, timepicker.ToString)
    Dim slider As VMSlider = vm.NewSlider("slider", "Slider", 0, 100, 0).SetDevicePositions(2, 2, 12, 6, 6, 6)
    cont.AddControl(slider.Slider, slider.ToString)
    'add container to page
End Sub

This produces...

33. BVM AddControl.png

NB: When using .SetDevicePositions and .AddControl one should not skip a RC when adding components.

The .New??? are just shortcuts for .Create??? and one can use either to create components.

For example, NewSwitch

Sub NewSwitch(sname As String, slabel As String, svalue As Object, sunchecked As Object, bPrimary As Boolean, iTabIndex As Int) As VMSwitch
    sname = sname.tolowercase
    Dim actName As String = sname
    Dim actID As String = sname
    If sname.IndexOf(".") >= 0 Then
        actName = MvField(sname,2,".")
    End If
    Dim el As VMSwitch = CreateSwitch(actName, module)
    el.SwitchBox.ActualID = actID
    el.SwitchBox.Host = $"${actName}field"$
    Return el
End Sub



Licensed User
Longtime User
Things the new version comes with: Alerts

37 BVM Alerts.png

vm.CreateAlert("a8", Me, "").SetContent("You've got {B}5{/B} new updates on your timeline!.").SetIcon("mdi-twitter") _
    .SetDismissible(True).SetBorder("left").SetColoredBorder(True).SetOutlined(True).SetColor(vm.COLOR_CYAN).SetElevation(2).AddToContainer(cont, 1, 2)


Licensed User
Longtime User
Things the new version comes with: Banners

38. BVM Banners.png

Dim banner1 As VMBanner = vm.CreateBanner("banner1", Me).SetTwoLine(True)
    Dim avat As VMAvatar = vm.CreateAvatar("avat1", Me).SetSlot("icon").SetSize("40").SetColorIntensity(vm.COLOR_DEEPPURPLE, vm.INTENSITY_ACCENT4)
    avat.SetIcon("mdi-lock","", CreateMap("color" : "white"), Null, Null)
    banner1.AddAction(vm.CreateButton("btnDismis", Me).SetLabel("Dismiss").SetPrimary(True).SetTransparent(True))
    banner1.AddAction(vm.CreateButton("btnRetry", Me).SetLabel("Retry").SetPrimary(True).SetTransparent(True))
    cont.AddComponent(1, 2, banner1.ToString)

Sub checkConnection(e As BANanoEvent)
    vm.showsnackbar("Check connection!")
End Sub


Licensed User
Longtime User
Things the new version comes with: Bottom Navigation

BVM BottomNavigation.gif

Dim bn3 As VMBottomNavigation = vm.CreateBottomNavigation("bn3", Me).SetVModel("bottomNav").SetDark(True).SetShift(True)
    Dim btnRecent2 As VMButton = vm.CreateButton("btnRecent2", Me).SetValue("recent")
    btnRecent2.AddComponent(vm.CreateIcon("", Me, "mdi-history").tostring)
    Dim btnFav2 As VMButton = vm.CreateButton("btnFav2", Me).SetValue("favorites")
    btnFav2.AddComponent(vm.CreateIcon("", Me, "mdi-heart").tostring)
    Dim btnNear2 As VMButton = vm.CreateButton("btnNear2", Me).SetValue("nearby")
    btnNear2.AddComponent(vm.CreateIcon("", Me, "mdi-map-marker").tostring)
    cont.AddComponent(2, 1, bn3.tostring)


Licensed User
Longtime User
Things the new version comes with: Bottom Sheet

BVM BottomSheet.gif

Sub BottomSheet2 As VMBottomSheet
    Dim bs As VMBottomSheet = vm.CreateBottomSheet("bs2", Me).SetVModel("bs2").SetInset(True)
    Dim s As VMSheet = vm.CreateSheet("s2", Me).SetTextCenter.SetHeight("200px")
    Dim lbl As VMLabel = vm.CreateLabel("lbl2").SetText("This is a botto sheet using inset prop!").SetParagraph
    s.Container.AddComponent(1, 1, lbl.ToString)
    Dim btnClose As VMButton = vm.CreateButton("btnCloseSheet2", Me).SetLabel("Close Sheet")
    s.Container.AddComponent(1, 1, btnClose.ToString)
    Return bs
End Sub