VanUI: A Collection of Grab 'n Go Reusable Utility and UI Components for VanJS
π Feedback and contribution are welcome and greatly appreciated! (source code)
Installation
Via NPM
The library is published as NPM package vanjs-ui. Run the following command to install the package:
npm install vanjs-ui
To use the NPM package, add this line to your script:
import { <components you want to import> } from "vanjs-ui"
Via a Script Tag
Alternatively, you can import VanUI from CDN via a <script type="text/javascript"> tag:
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/van-ui.nomodule.min.js"></script>
https://cdn.jsdelivr.net/npm/[email protected]/dist/van-ui.nomodule.js can be used for the non-minified version.
Note that: VanJS needs to be imported via a <script type="text/javascript"> tag for VanUI to work properly.
Try on jsfiddle: Modal, MessageBoard.
TypeScript Support for Script Tag Integration
To get TypeScript support for <script> tag integration, download van-ui.d.ts and add the code like following at the top of your .ts file:
import type { Modal as ModalType } from "./van-ui.d.ts"
declare const Modal: typeof ModalType
Documentation
The following components have been implemented so far:
- Utility components:
- UI components:
Await
Author: @Hunter-Gu
Await is a utility component that helps you build UI components based on asynchronous data (i.e.: a JavaScript Promise object).
Signature
Await({
value, // A `Promise` object for asynchronous data
container, // The container of the result. Default `div`
Loading, // What to render when the data is being loaded
Error, // What to render when error occurs
}, children) => <The created UI element>
The children parameter (type: (data: T) => ValidChildDomValue) is a function that takes the resolved data as input and returns a valid child DOM value (Node, primitives, null or undefined), used to indicate what to render after the data is loaded.
Examples
Preview with CodeSandbox.
Example 1 (fetching the number of GitHub stars):
const Example1 = () => {
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
const fetchWithDelay = (url: string, waitMs: number) =>
sleep(waitMs).then(() => fetch(url)).then(r => r.json())
const fetchStar = () =>
fetchWithDelay("https://api.github.com/repos/vanjs-org/van", 1000)
.then(data => data.stargazers_count)
const data = van.state(fetchStar())
return [
() => h2(
"GitHub Stars: ",
Await({
value: data.val, container: span,
Loading: () => "π Loading...",
Error: () => "π Request failed.",
}, starNumber => `βοΈ ${starNumber}!`)
),
() => Await({
value: data.val,
Loading: () => '',
}, () => button({onclick: () => (data.val = fetchStar())}, "Refetch")),
]
}
Example 2 (parallel Await):
const Example2 = () => {
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
const loadNumber = () =>
sleep(Math.random() * 1000).then(() => Math.floor(Math.random() * 10))
const a = van.state(loadNumber()), b = van.state(loadNumber())
return [
h2("Parallel Await"),
() => {
const sum = van.derive(() => Promise.all([a.val, b.val]).then(([a, b]) => a + b))
return Await({
value: sum.val,
Loading: () => div(
Await({value: a.val, Loading: () => "π Loading a..."}, () => "Done"),
Await({value: b.val, Loading: () => "π Loading b..."}, () => "Done"),
),
}, sum => "a + b = " + sum)
},
p(button({onclick: () => (a.val = loadNumber(), b.val = loadNumber())}, "Reload")),
]
}
Property Reference
value: TypePromise. Required. The asynchronous data that the result UI element is based on.container: TypeTagFunction<Element>. Defaultdiv(van.tags.div). Optional. The type of the wrapper HTML element for the result.Loading: Type() => ValidChildDomValue. Optional. If specified, indicates what to render when the asynchronous data is being loaded.Error: Type(reason: Error) => ValidChildDomValue. Optional. If specified, indicates what to render when error occurs while fetching the asynchronous data.
Modal
Creates a modal window on top of the current page.
Signature
Modal({...props}, ...children) => <The created modal window>
Examples
Preview with CodeSandbox.
Example 1:
const closed = van.state(false)
van.add(document.body, Modal({closed},
p("Hello, World!"),
div({style: "display: flex; justify-content: center;"},
button({onclick: () => closed.val = true}, "Ok"),
),
))
Example 2:
const closed = van.state(false)
const formDom = form(
div(input({type: "radio", name: "lang", value: "Zig", checked: true}), "Zig"),
div(input({type: "radio", name: "lang", value: "Rust"}), "Rust"),
div(input({type: "radio", name: "lang", value: "Kotlin"}), "Kotlin"),
div(input({type: "radio", name: "lang", value: "TypeScript"}), "TypeScript"),
div(input({type: "radio", name: "lang", value: "JavaScript"}), "JavaScript"),
)
const onOk = () => {
const lang = (<HTMLInputElement>formDom.querySelector("input:checked")).value
alert(lang + " is a good language π")
closed.val = true
}
van.add(document.body, Modal({closed, blurBackground: true, clickBackgroundToClose: true},
p("What's your favorite programming language?"),
formDom,
p({style: "display: flex; justify-content: space-evenly;"},
button({onclick: onOk}, "Ok"),
button({onclick: () => closed.val = true}, "Cancel"),
)
))
Property Reference
closed: TypeState<boolean>. Required. AStateobject used to close the created modal window. Basically, settingclosed.val = truewill close the created modal window. You can also subscribe the closing event of the modal window viavan.derive.backgroundColor: Typestring. Default"rgba(0,0,0,.5)". Optional. The color of the background overlay when the modal is activated.blurBackground: Typeboolean. Defaultfalse. Optional. Whether to blur the background.clickBackgroundToClose: Typeboolean. Defaultfalse. Optional. Iftrue, clicking the background will close the created modal.backgroundClass: Typestring. Default"". Optional. Theclassattribute of the background overlay. You can specify multiple CSS classes separated by" ".backgroundStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the background overlay.modalClass: Typestring. Default"". Optional. Theclassattribute of the created modal element. You can specify multiple CSS classes separated by" ".modalStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the created modal element.
Tabs
Creates a tab-view for tabs specified by the user.
Signature
Tabs({...props}, tabContents) => <The created tab-view>
The tabContents parameter is an object whose keys are the titles of the tabs and values (type: ChildDom) are the DOM element(s) for the tab contents.
Example
Preview with CodeSandbox.
van.add(document.body, Tabs(
{
style: "max-width: 500px;",
tabButtonActiveColor: "white",
tabButtonBorderStyle: "none",
tabButtonRowStyleOverrides: {
"padding-left": "12px",
},
},
{
Home: p(
"Welcome to ", b("VanJS"), " - the smallest reactive UI framework in the world.",
),
"Getting Started": [
p("To install the ", b("VanJS"), " NPM package, run the line below:"),
pre(code("npm install vanjs-core")),
],
About: p(
"The author of ", b("VanJS"), " is ",
a({href: "https://github.com/Tao-VanJS"}, " Tao Xin"), "."
),
},
))
Property Reference
activeTab: TypeState<string>. Optional. If specified, you can activate a tab via the specifiedStateobject withactiveTab.val = "<tab title>", and subscribe to the changes of active tab viavan.derive.activeTabDisplay: Typestring. Default"block". Optional. ThedisplayCSS property for the content of the active tab.resultClass: Typestring. Default"". Optional. Theclassattribute of the result DOM element. You can specify multiple CSS classes separated by" ".style: Typestring. Default"". Optional. Thestyleproperty of the result DOM element.tabButtonRowColor: Typestring. Default"#f1f1f1". Optional. The background color of the container of tab buttons.tabButtonBorderStyle: Typestring. Default1px solid #000. Optional. The style of borders between tab buttons.tabButtonHoverColor: Typestring. Default"#ddd". Optional. The color when the tab button is hovered.tabButtonActiveColor: Typestring. Default"#ccc". Optional. The color of the tab button for the currently active tab.transitionSec: Typenumber. Default0.3. Optional. The duration of the transition when tab buttons change color.tabButtonRowClass: Typestring. Default"". Optional. Theclassattribute of the container of tab buttons. You can specify multiple CSS classes separated by" ".tabButtonRowStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the container of tab buttons.tabButtonClass: Typestring. Default"". Theclassattribute of tab buttons. You can specify multiple CSS classes separated by" ".tabButtonStyleOverrides: TypeRecord<string, string | number>. Default{}. A property bag for the styles you want to override for tab buttons. You can specify multiple CSS classes separated by" ".tabContentClass: Typestring. Default"". Theclassattribute of tab contents. You can specify multiple CSS classes separated by" ".tabContentStyleOverrides: TypeRecord<string, string | number>. Default{}. A property bag for the styles you want to override for tab contents.
MessageBoard
Creates a message board to show messages on the screen.
Signature
To create a message board:
const board = new MessageBoard({...props})
Then you can show messages with show method:
board.show({...props}) => <The created DOM node for the message, which is also appended to the message board>
Optionally, you can remove the DOM node of the message board with remove method:
board.remove()
Examples
Preview with CodeSandbox.
const board = new MessageBoard({top: "20px"})
const example1 = () => board.show({message: "Hi!", durationSec: 1})
const example2 = () => board.show(
{message: ["Welcome to ", a({href: "https://vanjs.org/", style: "color: #0099FF"}, "π¦VanJS"), "!"], closer: "β"})
const closed = van.state(false)
const example3 = () => {
closed.val = false
board.show({message: "Press ESC to close this message", closed})
}
document.addEventListener("keydown", e => e.key === "Escape" && (closed.val = true))
Property Reference
Message board properties:
top: Typestring. Optional. ThetopCSS property of the message board.bottom: Typestring. Optional. ThebottomCSS property of the message board. Exactly one oftopandbottomshould be specified.backgroundColor: Typestring. Default"#333D". Optional. The background color of the messages shown on the message board.fontColor: Typestring. Default"white". Optional. The font color of the messages shown on the message board.fadeOutSec: Typenumber. Default0.3. Optional. The duration of the fade out animation when messages are being closed.boardClass: Typestring. Default"". Optional. Theclassattribute of the message board. You can specify multiple CSS classes separated by" ".boardStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the message board.messageClass: Typestring. Default"". Optional. Theclassattribute of the message shown on the message board. You can specify multiple CSS classes separated by" ".messageStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the message shown on the message board.closerClass: Typestring. Default"". Optional. Theclassattribute of the message closer. You can specify multiple CSS classes separated by" ".closerStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the message closer.
Message properties:
message: TypeChildDom. Required. OneChildDomor multipleChildDomas anArrayfor the message we want to show.closer: TypeChildDom. Optional. If specified, we will render a closer DOM node with oneChildDomor multipleChildDoms as anArraywhich can be clicked to close the shown message.durationSec: Typenumber. Optional. If specified, the shown message will be automatically closed afterdurationSecseconds.closed: TypeState<boolean>. Optional. If specified, the shown message can be closed via theclosedStateobject withclosed.val = true. You can also subscribe the closing event of the message viavan.derive.
Tooltip
Creates a tooltip above a DOM node which typically shows when the DOM node is being hovered.
Signature
Tooltip({...props}) => <The created tooltip element>
Examples
Preview with CodeSandbox.
const tooltip1Show = van.state(false)
const tooltip2Show = van.state(false)
const count = van.state(0)
const tooltip2Text = van.derive(() => `Count: ${count.val}`)
const tooltip3Show = van.state(false)
van.add(document.body,
button({
style: "position: relative;",
onmouseenter: () => tooltip1Show.val = true,
onmouseleave: () => tooltip1Show.val = false,
}, "Normal Tooltip", Tooltip({text: "Hi!", show: tooltip1Show})), " ",
button({
style: "position: relative;",
onmouseenter: () => tooltip2Show.val = true,
onmouseleave: () => tooltip2Show.val = false,
onclick: () => ++count.val
}, "Increment Counter", Tooltip({text: tooltip2Text, show: tooltip2Show})), " ",
button({
style: "position: relative;",
onmouseenter: () => tooltip3Show.val = true,
onmouseleave: () => tooltip3Show.val = false,
}, "Slow Fade-in", Tooltip({text: "Hi from the sloth!", show: tooltip3Show, fadeInSec: 5})),
)
Note that the lines:
{
style: "position: relative;",
onmouseenter: () => ...Show.val = true,
onmouseleave: () => ...Show.val = false,
}
are needed for the tooltip element to be shown properly.
Property Reference
text: Typestring | State<string>. Required. The text shown in the tooltip. If aStateobject is specified, you can set the text withtext.val = ....show: TypeState<boolean>. Required. TheStateobject to control whether to show the tooltip or not.width: Typestring. Default"200px". Optional. The width of the tooltip.backgroundColor: Typestring. Default"#333D". Optional. The background color of the tooltip.fontColor: Typestring. Default:"white". Optional. The font color of the tooltip.fadeInSec: Typenumber. Default0.3. Optional. The duration of the fade-in animation.tooltipClass: Typestring. Default"". Optional. Theclassattribute of the tooltip. You can specify multiple CSS classes separated by" ".tooltipStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the tooltip.triangleClass: Typestring. Default"". Optional. Theclassattribute of the triangle in the bottom. You can specify multiple CSS classes separated by" ".triangleStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the triangle in the bottom.
Toggle
Creates a toggle switch that can be turned on and off.
Signature
Toggle({...props}) => <The created toggle switch>
Example
Preview with CodeSandbox.
van.add(document.body, Toggle({
on: true,
size: 2,
onColor: "#4CAF50"
}))
Property Reference
on: Typeboolean | State<boolean>. Defaultfalse. Optional. A boolean or a boolean-typedStateobject to indicate the status of the toggle. If aStateobject is specified, you can turn on/off the toggle via the specifiedStateobject withon.val = <true|false>, and subscribe to the status change of the toggle viavan.derive.size: Typenumber. Default1. Optional. The size of the toggle.1means the height of the toggle is1rem.cursor: Typestring. Defaultpointer. Optional. ThecursorCSS property of the toggle.ofColor: Typestring. Default"#ccc". Optional. The color of the toggle when it's off.onColor: Typestring. Default"#2196F3". Optional. The color of the toggle when it's on.circleColor: Typestring. Default"white". Optional. The color of the toggling circle.toggleClass: Typestring. Default"". Optional. Theclassattribute of the toggle. You can specify multiple CSS classes separated by" ".toggleStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the toggle.sliderClass: Typestring. Default"". Optional. Theclassattribute of the slider. You can specify multiple CSS classes separated by" ".sliderStyleOverrides. TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the slider.circleClass. Typestring. Default"". Optional. Theclassattribute of the toggling circle. You can specify multiple CSS classes separated by" ".circleStyleOverrides. TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the toggling circle.circleWhenOnStyleOverrides. TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the toggling circle. Typically this is used to override thetransformCSS property if the dimensions of the toggle is overridden.
OptionGroup
Creates a group of button-shaped options where only one option can be selected. This is functionally similar to a radio group but with a different appearance.
Signature
OptionGroup({...props}, options) => <The created option group>
The options parameter is a string[] for all the options.
Example
Preview with CodeSandbox.
const selected = van.state("")
const options = ["Water", "Coffee", "Juice"]
van.add(document.body,
p("What would you like to drink?"),
OptionGroup({selected}, options),
p(() => options.includes(selected.val) ?
span(b("You selected:"), " ", selected) : b("You haven't selected anything.")),
)
Property Reference
selected: TypeState<string>. Required. AStateobject for the currently selected option. You can change the selected option withselected.val = <option string>, and subscribe to the selection change viavan.derive.normalColor: Typestring. Default"#e2eef7". Optional. The color of the option when it's not selected or hovered.hoverColor: Typestring. Default"#c1d4e9". Optional. The color of the option when it's hovered.selectedColor: Typestring. Default"#90b6d9". Optional. The color of the option when it's selected.selectedHoverColor: Typestring. Default"#7fa5c8". Optional. The color of the option when it's selected and hovered.fontColor: Typestring. Default"black". Optional. The font color of the options.transitionSec: Typenumber. Default0.3. Optional. The duration of the transition when the options change color.optionGroupClass: Typestring. Default"". Optional. Theclassattribute of the entire option group. You can specify multiple CSS classes separated by" ".optionGroupStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the entire option group.optionClass: Typestring. Default"". Optional. Theclassattribute of the options. You can specify multiple CSS classes separated by" ".optionStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the options.
Banner
Creates a banner element for the current container.
Signature
Banner({...props}, ...children) => <The created banner element>
Examples
Preview with CodeSandbox.
van.add(document.body,
h2("Sticky Banner"),
div({style: "width: 300px; height: 200px; overflow-y: auto; border: 1px solid #000;"},
Banner({sticky: true}, "πHello πΊοΈWorld"),
div({style: "padding: 0 10px"}, Array.from({length: 10}).map((_, i) => p("Line ", i))),
),
h2("Non-sticky Banner"),
div({style: "width: 300px; height: 200px; overflow-y: auto; border: 1px solid #000;"},
Banner({sticky: false}, "πHello ", a({href: "https://vanjs.org/"}, "π¦VanJS")),
div({style: "padding: 0 10px"}, Array.from({length: 10}).map((_, i) => p("Line ", i))),
),
)
Property Reference
backgroundColor: Typestring. Default#fff1a8. Optional. The background color of the banner.fontColor: Typestring. Defaultcurrentcolor. Optional. The font color of the banner.sticky: Typeboolean. Defaultfalse. Optional. Whether the banner is sticky on the top.bannerClass: Typestring. Default"". Optional. Theclassattribute of the created banner element. You can specify multiple CSS classes separated by" ".bannerStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the created banner element.
FloatingWindow
Author: @Duffscs
Creates a movable and resizable floating window.
Signature
FloatingWindow({...props}, ...children) => <The created floating window>
Examples
Preview with CodeSandbox.
Window with custom close button:
const closed = van.state(false)
const width = van.state(300), height = van.state(220)
van.add(document.body, FloatingWindow(
{title: "Example Window 1", closed, width, height, closeCross: null},
div({style: "display: flex; flex-direction: column; justify-content: center;"},
p("Hello, World!"),
button({onclick: () => width.val *= 2}, "Double Width"),
button({onclick: () => height.val *= 2}, "Double Height"),
button({onclick: () => closed.val = true}, "Close Window"),
),
))
Window with integrated close button:
van.add(document.body, FloatingWindow(
{title: "Example Window 2", x: 150, y: 150, headerColor: "lightblue"},
div({style: "display: flex; justify-content: center;"},
p("This is another floating window!"),
),
))
Close button with custom appearance:
van.add(document.body, FloatingWindow(
{
title: "Example Window 3", x: 175, y: 175, closeCross: "β",
crossHoverStyleOverrides: {"background-color": "white"},
},
div({style: "display: flex; justify-content: center;"},
p("This is a floating window with custom cross button!"),
),
))
Window with Tabs:
const closed = van.state(false)
van.add(document.body, FloatingWindow(
{
closed, x: 200, y: 200, width: 500, height: 300,
childrenContainerStyleOverrides: { padding: 0 },
},
div(
span({
class: "vanui-window-cross",
style: "position: absolute; top: 8px; right: 8px;cursor: pointer;",
onclick: () => closed.val = true,
}, "Γ"),
Tabs(
{
style: "width: 100%;",
tabButtonActiveColor: "white",
tabButtonBorderStyle: "none",
tabButtonRowColor: "lightblue",
tabButtonRowStyleOverrides: {height: "2.5rem"},
tabButtonStyleOverrides: {height: "100%"},
},
{
Home: p(
"Welcome to ", b("VanJS"), " - the smallest reactive UI framework in the world.",
),
"Getting Started": [
p("To install the ", b("VanJS"), " NPM package, run the line below:"),
pre(code("npm install vanjs-core")),
],
About: p(
"The author of ", b("VanJS"), " is ",
a({href: "https://github.com/Tao-VanJS"}, " Tao Xin"), "."
),
},
)
)
))
Window without header or integrated close button:
const closed = van.state(false)
van.add(document.body, FloatingWindow(
{
closed, x: 300, y: 300, width: 500, height: 300,
windowStyleOverrides: {"background-color": "lightgray"},
childrenContainerStyleOverrides: {
display: "flex",
"align-items": "center",
"justify-content": "center",
height: "100%",
}
},
button({onclick: () => closed.val = true}, "Close Window"),
))
Window showing z-index:
const zIndex = van.state(1)
van.add(document.body, FloatingWindow(
{title: ["z-index: ", zIndex], x: 200, y: 200, width: 300, height: 100, zIndex},
))
Window with custom stacking:
const zIndex = van.state(1)
van.add(document.body, FloatingWindow(
{title: "Custom stacking", x: 300, y: 300, customStacking: true, zIndex},
div({style: "display: flex; justify-content: space-between;"},
button({onclick: () => zIndex.val++}, "+"),
p("z-index: ", zIndex),
button({onclick: () => zIndex.val--}, "-"),
),
div({style: "display: flex; justify-content: center;"},
button({onclick: () => zIndex.val = topMostZIndex()}, "Bring to Front"),
),
))
Non-movable window:
van.add(document.body, FloatingWindow(
{title: "Not Movable", disableMove: true},
div({style: "display: flex; justify-content: center;"},
p("This window is not movable!"),
),
))
Non-movable window without title:
const closed = van.state(false)
van.add(document.body, FloatingWindow(
{closed, x: 150, y: 150, disableMove: true},
div(
p("This window is not movable!"),
p({style: "display: flex; justify-content: center;"},
button({onclick: () => closed.val = true}, "Close")
),
),
))
Non-resizable window:
van.add(document.body, FloatingWindow(
{title: "Not Resizable", x: 200, y: 200, disableResize: true},
div(
p({style: "display: flex; justify-content: center;"}, "This window is not resizable!"),
),
))
Default z-index Stacking
By default, the z-index CSS property of each window comes from the sequence: 1, 2, 3, .... Whenever a new window is created or is interacted with (onmousedown event is triggered), we assign the z-index property of the window to the next number in the sequence. This way, we are making sure that newly created or interacted windows are always brought to the front.
You can override the default stacking behavior by specifying {customStacking: true} in props. This way, you can manually control the z-index of the window via a VanJS state.
Property Reference
title: TypeChildDom. Optional. OneChildDomor multipleChildDomas anArrayfor the title of the created window. If not specified, the window won't have a title.closed: TypeState<boolean>. Optional. If specified, the created window can be closed via theclosedStateobject withclosed.val = true. You can also subscribe the closing event of the created window viavan.derive.x: Typenumber | State<number>. Default100. Optional. The x-coordinate of the created window, in pixels.y: Typenumber | State<number>. Default100. Optional. The y-coordinate of the created window, in pixels.width: Typenumber | State<number>. Default300. Optional. The width of the created window, in pixels.height: Typenumber | State<number>. Default200. Optional. The height of the created window, in pixels.closeCross: TypeChildDom. Default"Γ". Optional. OneChildDomor multipleChildDomas anArrayfor the close button of the created window. If its value isnull, there won't be a close button. Iftitleproperty is not specified, this property will be ignored and there won't be a close button.customStacking: typeboolean. Defaultfalse. Optional. Iftrue, defaultz-indexstacking rule won't be triggered. Users are expected to manually set thez-indexproperty of the created window via theStateobject forz-indexproperty below.zIndex: typenumber | State<number>. Optional. If aStateobject is specified, you can use theStateobject to track the change ofz-indexproperty viavan.derive. IfcustomTrackingistrue, you can use this property to manually set thez-indexproperty of the created window.disableMove: typeboolean. Defaultfalse. Optional. Iftrue, the created window can't be moved.disableResize: typeboolean. Defaultfalse. Optional. Iftrue, the created window can't be resized.headerColor: typestring. Default"lightgray". Optional. The background color of the window header (title bar).windowClass: Typestring. Default"". Optional. Theclassattribute of the created window. You can specify multiple CSS classes separated by" ".windowStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the created window.headerClass: Typestring. Default"". Optional. Theclassattribute of the window header (title bar). You can specify multiple CSS classes separated by" ".headerStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the window header (title bar).childrenContainerClass: Typestring. Default"". Optional. Theclassattribute of the container forchildrenDOM nodes. You can specify multiple CSS classes separated by" ".childrenContainerStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the container ofchildrenDOM nodes.crossClass: Typestring. Default"". Optional. Theclassattribute of the close button. You can specify multiple CSS classes separated by" ".crossStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the close button.crossHoverClass: Typestring. Default"". Optional. Theclassattribute of the close button when it's hovered over. You can specify multiple CSS classes separated by" ".crossStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the close button when it's hovered over.
choose
Creates a Modal component that lets the user choose among given options, returns a Promise that resolves when user makes the choice (resolves to the chosen string), or cancels (resolves to null).
Signature
choose({...props}) => Promise<string | null>
Examples
Preview with CodeSandbox.
Example 1:
const choice = await choose({
label: "Choose a color:",
options: ["Red", "Green", "Blue"],
})
choice && van.add(document.body, div("You chose: ", b(choice)))
Example 2:
const choice = await choose({
label: "Choose a South American country:",
options: [
"π¦π· Argentina", "π§π΄ Bolivia", "π§π· Brazil", "π¨π± Chile", "π¨π΄ Colombia", "πͺπ¨ Ecuador",
"π¬πΎ Guyana", "π΅πΎ Paraguay", "π΅πͺ Peru", "πΈπ· Suriname", "πΊπΎ Uruguay", "π»πͺ Venezuela",
],
showTextFilter: true,
selectedColor: "blue",
cyclicalNav: true,
customModalProps: {
blurBackground: true,
modalStyleOverrides: {height: "300px"},
clickBackgroundToClose: true,
},
selectedStyleOverrides: {color: "white"},
})
choice && van.add(document.body, div("You chose: ", b(choice)))
Property Reference
label: TypeChildDom. Required. OneChildDomor multipleChildDomas anArrayfor the label you want to show.options: Typestring[]. Required. The options of the choice.showTextFilter: Typeboolean. Defaultfalse. Optional. Whether to show a text filter for the options.selectedColor: Typestring. Default"#f5f5f5". Optional. The background color of the currently selected option.cyclicalNav: Typeboolean. Defaultfalse. Optional. Whether to navigate through the options via arrow keys in a cyclical manner. That is, ifcyclicalNavis on, when you reach the end of the list, pressing the down arrow key will take you back to the beginning, and vice versa for going up the list with the up arrow key.customModalProps: Type: property bags for theModalcomponent (except theclosedfield). Default{}. Optional. The custom properties for theModalcomponent you want to specify.textFilterClass: Typestring. Default"". Optional. Theclassattribute of the text filter. You can specify multiple CSS classes separated by" ".textFilterStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the text filter.optionsContainerClass: Typestring. Default"". Optional. Theclassattribute of the container of all options. You can specify multiple CSS classes separated by" ".optionsContainerStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the container of all options.optionClass: Typestring. Default"". Optional. Theclassattribute of an individual option. You can specify multiple CSS classes separated by" ".optionStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for an individual option.selectedClass: Typestring. Default"". Optional. Theclassattribute of the currently selected option. You can specify multiple CSS classes separated by" ".selectedStyleOverrides: TypeRecord<string, string | number>. Default{}. Optional. A property bag for the styles you want to override for the currently selected option.
Property Bag for Style Overrides
In the API of VanUI, you can specify an object as a property bag to override the styles of the created elements. The keys of the property bag are CSS property names, and the values of the property bag are CSS property values. Sample values of the property bag:
{
"z-index": 1000,
"background-color": "rgba(0,0,0,.8)",
}
{
"border-radius": "0.2rem",
padding: "0.8rem",
"background-color": "yellow",
}