vanjs-ui
v0.11.5
Published
A collection of grab-n-go reusable UI components for VanJS
Downloads
1,316
Maintainers
Readme
VanUI: A Collection of Grab 'n Go Reusable Utility and UI Components for VanJS
More on VanJS:
🙏 Feedback and contribution are welcome and greatly appreciated!
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 Star: ",
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},
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. AState
object used to close the created modal window. Basically, settingclosed.val = true
will 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.backgroundClass
: Typestring
. Default""
. Optional. Theclass
attribute 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. Theclass
attribute 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 specifiedState
object withactiveTab.val = "<tab title>"
, and subscribe to the changes of active tab viavan.derive
.resultClass
: Typestring
. Default""
. Optional. Theclass
attribute of the result DOM element. You can specify multiple CSS classes separated by" "
.style
: Typestring
. Default""
. Optional. Thestyle
property 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. Theclass
attribute 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""
. Theclass
attribute 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""
. Theclass
attribute 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. Thetop
CSS property of the message board.bottom
: Typestring
. Optional. Thebottom
CSS property of the message board. Exactly one oftop
andbottom
should 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. Theclass
attribute 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. Theclass
attribute 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. Theclass
attribute 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. OneChildDom
or multipleChildDom
as anArray
for the message we want to show.closer
: TypeChildDom
. Optional. If specified, we will render a closer DOM node with oneChildDom
or multipleChildDom
s as anArray
which can be clicked to close the shown message.durationSec
: Typenumber
. Optional. If specified, the shown message will be automatically closed afterdurationSec
seconds.closed
: TypeState<boolean>
. Optional. If specified, the shown message can be closed via theclosed
State
object 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 aState
object is specified, you can set the text withtext.val = ...
.show
: TypeState<boolean>
. Required. TheState
object 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. Theclass
attribute 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. Theclass
attribute 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-typedState
object to indicate the status of the toggle. If aState
object is specified, you can turn on/off the toggle via the specifiedState
object withon.val = <true|false>
, and subscribe to the status change of the toggle viavan.derive
.size
: Typenumber
. Default1
. Optional. The size of the toggle.1
means the height of the toggle is1rem
.cursor
: Typestring
. Defaultpointer
. Optional. Thecursor
CSS 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. Theclass
attribute 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. Theclass
attribute 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. Theclass
attribute 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 thetransform
CSS 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. AState
object 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. Theclass
attribute 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. Theclass
attribute 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. Theclass
attribute 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. OneChildDom
or multipleChildDom
as anArray
for 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 theclosed
State
object 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. OneChildDom
or multipleChildDom
as anArray
for the close button of the created window. If its value isnull
, there won't be a close button. Iftitle
property is not specified, this property will be ignored and there won't be a close button.customStacking
: typeboolean
. Defaultfalse
. Optional. Iftrue
, defaultz-index
stacking rule won't be triggered. Users are expected to manually set thez-index
property of the created window via theState
object forz-index
property below.zIndex
: typenumber | State<number>
. Optional. If aState
object is specified, you can use theState
object to track the change ofz-index
property viavan.derive
. IfcustomTracking
istrue
, you can use this property to manually set thez-index
property 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. Theclass
attribute 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. Theclass
attribute 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. Theclass
attribute of the container forchildren
DOM 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 ofchildren
DOM nodes.crossClass
: Typestring
. Default""
. Optional. Theclass
attribute 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. Theclass
attribute 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"},
},
selectedStyleOverrides: {color: "white"},
})
choice && van.add(document.body, div("You chose: ", b(choice)))
Property Reference
label
: Typestring
. Required. 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 in a cyclical manner. That is, whencyclicalNav
is 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 theModal
component (except theclosed
field). Default{}
. Optional. The custom properties for theModal
component you want to specify.textFilterClass
: Typestring
. Default""
. Optional. Theclass
attribute 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. Theclass
attribute 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. Theclass
attribute 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. Theclass
attribute 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",
}