Package {shinylight}


Title: Web Interface to 'R' Functions
Version: 1.3
Date: 2026-09-03
Description: Web front end for your 'R' functions producing plots or tables. If you have a function or set of related functions, you can make them available over the internet through a web browser. This is the same motivation as the 'shiny' package, but note that the development of 'shinylight' is not in any way linked to that of 'shiny' (beyond the use of the 'httpuv' package). You might prefer 'shinylight' to 'shiny' if you want a lighter weight deployment with easier horizontal scaling, or if you want to develop your front end yourself in JavaScript and HTML just using a lightweight remote procedure call interface to your R code on the server.
Author: Pieter Vermeesch [aut], Tim Band [aut, cre]
Maintainer: Tim Band <t.band@ucl.ac.uk>
Depends: R (≥ 4.0.0)
Imports: grDevices (≥ 3.6.2), httpuv (≥ 1.5.4), jsonlite (≥ 2.0.0), later (≥ 1.0)
Suggests: websocket (≥ 1.4.1)
License: GPL-3
RoxygenNote: 7.3.1
Encoding: UTF-8
NeedsCompilation: no
Packaged: 2026-10-02 14:23:56 UTC; tim
Repository: CRAN
Date/Publication: 2026-10-02 15:20:02 UTC

Opens a browser to look at the server

Description

Opens a browser to look at the server

Usage

browseTo(server)

Arguments

server

The server to browse to

Value

No return value


Encodes a data frame as a CSV file to be downloaded

Description

Encodes a data frame as a CSV file to be downloaded

Usage

downloadCsv(results)

Arguments

results

Data frame to be returned

Value

A list to be returned to the browser describing a CSV file to be downloaded.


Renders a plot as a base64-encoded image

Description

Renders a plot as a base64-encoded image

Usage

encodePlot(device, mimeType, width, height, plotFn)

Arguments

device

Graphics device function, such as grDevices::png or grDevices::pdf

mimeType

Mime type for the data produced by device

width

Width of the plot in units applicable to device

height

Height of the plot in units applicable to device

plotFn

Function to call to perform the plot

Value

list with two keys, whose values can each be NULL: 'plot' is a plot in HTML img src form and 'data' is a data frame or other non-plot result.

Examples

pdf <- encodePlot(grDevices::png, "image/png", 200, 300, function() {
  barplot(c(1, 2, 3, 4))
})
grDevices::png()  # workaround; you do not have to do this

Renders a plot as a base64-encoded PNG

Description

The result can be set as the src attribute of an <img> element in HTML.

Usage

encodePlotAs(format, plotFn)

Arguments

format

An object specifying the output, with the following members: format$type is "png", "pdf" or "csv", and format$width and format$height are the dimensions of the PDF (in inches) or PNG (in pixels) if appropriate.

plotFn

Function to call to perform the plot

Details

You will not need to call this function unless you want to return more than one plot per call, as the last plot produced will be returned in the plot property of the result from shinylight.call anyway.

Value

list with two keys, whose values can each be NULL: 'plot' is a plot in HTML img src form and 'data' is a data frame or other non-plot result.

A list with an element named plot containing the plot encoded as required either for an HTML image element's src attribute, or a element's href attribute. If the function returns a matrix or data frame, this will be returned in the list's data element.

See Also

rrpcServer

Examples

pdf <- encodePlotAs(list(type="pdf", width=7, height=8), function() {
  barplot(c(1, 2, 3, 4))
})
grDevices::png()  # workaround; you do not have to do this

JavaScript function: Starts the Shinylight Framework, if you want to use it.

Description

The Shinylight Framework allows you to declare all your functions in R and have a nice-looking web front end for your code without having to write any JavaScript.

You should never need to call this function yourself; if you do not provide your own index.html, the default Shinylight one will be used that will call this function on page load.

Using the Shinylight Framework entails calling the slServer function with the interface argument set to list(getSchema=schema), where schema is defined in the following section.

Arguments

The Schema

It is a list with the following members:

functions

a list of functions (keyed by their names), each of which is a list with the following members:

params

a list of the main parameters the function accepts. The keys are the parameter names and the values are keys into the schema's params list.

optiongroups

a vector of keys into the schema's optiongroups list giving other parameters to this function.

functiongroups

optional: the menu structure for the functions menu. Each item in the list is either a function name (a string referencing a key in the functions list) or a list representing a submenu. Submenu keys are the name to be displayed in the list, which can be overridden in the app.json file's functions object, just like providing localized names for functions.

params

a list of the parameters the functions take, each of which is a list with the following members:

type

either a key into the schema's types list, giving the type of this parameter or the values it can take, or one of a set of standard types:

'b'

Boolean

'f'

Floating point

'u8'

8-bit unsigned integer

'color'

Colour

'subheader'

Vector of settings the user can choose for each column using selectors in the subheader row. This is usually used to select units (for example percent-by-weight versus parts-per-million) for the columns.

data

a key into the schema's data list, giving initial or example data for this parameter.

types

a list of types with keys referened from the schema's params lists's type values. The values are a list with the following members:

kind

Mandatory; one of:

'enum'

Enumeration type

'column'

A column from the input grid

values

A vector of permitted values (only if kind='enum')

factors

Only if kind='enum' and this enum is used as the unit type for some column; a vector of factors to multiply column data by if the unit is changed by the user. Must have the same number of elements as the values vector. For every n, factors[[n]] of unit values[[n]] must be equal. For example, if values=c('mm', 'cm', 'inch') then factors could be c(25.4, 2.54, 1.0).

subtype

Only if kind='column'. The type of data that can be entered into the column. Currenly only 'f' works well.

unittype

Optional and only if kind='column'. The name of an enum type defining the units that the data in this column can be expressed in.

data

A list of initial data with which table columns and controls will be populated. Can be a single value or vector (or list) as appropriate.

optiongroups

A list of option groups. Each one is a set of parameters that can be added as a block to functions that want them. Each element is a list with the following keys:

type

The same as for param's type: either a key into the schema's types list or one of the standard types ('b', 'u8', 'f' or 'color').

initial

The initial value for this option.

There is one special key in the optiongroups list; this is the framework key. This is reserved for options that apply to the framework itself, not to any of your functions. So far, the only option it has is autorefresh=list(type="b", initial=FALSE). You can set its initial value to TRUE if you prefer. If you add this option, it controls whether the GUI has a "Calculate" button (FALSE) or whether the output should refresh a second or two after the user finishes changing parameters (TRUE).

Localization

To display human-friendly text on the controls and to get tooltip help text, you need one or more localization files. These files are named inst/www/locales/XX/app.json where XX is replaced with the appropriate ISO language code.

These files are JSON files containing an object with the following keys:

title

Text for the link to put in the top left

homepage

Destination for the link to put in the top left

functions

One pair of translations for each function in the schema.

params

One pair of translations for each parameter in the schema.

optiongroups

Each of the optiongroups in the schema gets a key which maps to an object which has the following keys:

@title

A translation pair for the option group itself.

...

One translation pair for each option in the group.

types

One object for each 'enum' type in the schema. Each value is an object with one key per possible enum value. Each value in this object is that enum value's translation pair.

A "translation pair" is an object with the following keys:

name

A short name

help

Tooltip text

See Also

toolkit.loadFileButton


Obtains the address that the server is listening on

Description

Obtains the address that the server is listening on

Usage

getAddress(server)

Arguments

server

The server (returned by slServer or slRunRServer)

Value

The HTTP address as protocol://address:port

Examples

server <- slServer(
  port = 50051,
  interface = list(
    multiply = function(x, y) { x * y }
  )
)
address <- getAddress(server)
# ...
slStop(server)
stopifnot(address == "http://127.0.0.1:50051")

Get index.html with (potentially) the JSON data in 'text' inserted.

Description

Get index.html with (potentially) the JSON data in 'text' inserted.

Usage

indexWithInit(text, path)

Arguments

text

The text to insert as shinylight_initial_data

path

File system path to the index.html file

Value

The updated text


Makes and starts a server for serving R calculations

Description

It will serve files from the app directories specified by appDirs. If a file is requested that is not in one of those directories, the files in Shinylight's own inst/www directory will be served. Some paths have special meanings: / returns /index.html, /lang/ is redirected to /locales/<language-code>/ depending on the language selected in the request's Accept-Language header (that is, the browser's language setting) and the availability of the file requested. A POST request to /init with a data parameter will return /index.html, except that if the file has a line containing shinylight_initial_data = then this line with be replaced with a line initializing shinylight_initial_data to the data passed. This is used in shinylight-framework to permit linking to a framework app with specific data preloaded – the text should be as is downloaded with the "Save Data" button. Of course, this is available to non-framework apps, too.

Usage

rrpcServer(
  interface,
  host = "0.0.0.0",
  port = NULL,
  appDirs = NULL,
  root = "/",
  initialize = NULL,
  testFunction = NULL
)

Arguments

interface

List of functions to be served. The names of the elements are the names that the client will use to call them.

host

Interface to listen on (default is '0.0.0.0', that is, all interfaces)

port

Port to listen on

appDirs

List of directories in which to find static files to serve

root

Root of the app on the server (with trailing slash)

initialize

A json string or list (that will be converted to a JSON string) to be passed to the JavaScript as initial data. For non-framework apps, the index.html must contain a line containing var shinylight_initial_data=, which will be replaced with code that sets shinylight_initial_data to this supplied JSON string.

testFunction

Function to be called if the /test endpoint is requested. If the function returns successfully, a 200 status will be returned. If not, a 500 status will be returned.

Value

The server object, can be passed to slStop


Returns a function that runs an R command

Description

If you set this as a part of your interface, like: runR=shinylight::runR(c("+", "plot", "c", "x", "y")) then you can call it from Javascript like this:

rrpc.call("runR", {
 Rcommand:"2+2"
}, function(x) {console.log(x);});
rrpc.call("runR", {
 Rcommand:"y<-c(2,0,1);plot(c(1,2,3),y);y",
 'rrpc.resultformat': {
   type: 'png',
   width: 200,
   height: 300,
 }
}, function(x) {img.setAttribute('src', x.plot[0])});

Usage

runR(symbolList)

Arguments

symbolList

A list of permitted symbols in the R command

Value

A function that can be passed as one of the elements of slServer's interface argument.

Examples

server <- slServer(
  port = 50051,
  interface = list(
    run_the_users_r_code = runR(
      list("c", "$", "list", "+", "-", "/", "*", "sqrt")
    )
  )
)
# ...
slStop(server)

Sends informational text to the client.

Description

During a slow remote procedure call, call this to inform the client of progress.

Usage

sendInfoText(text)

Arguments

text

The text to send

Value

No return value

See Also

sendProgress for sending a progress completion ratio to the user.

Examples

server <- slServer(
  port = 50051,
  interface = list(long_and_complicated = function(x) {
    # First part of work that takes some time
    # ...
    sendInfoText("We are about half way through")
    # Second part of work that takes some time
    # ...
  })
)
# ...
slStop(server)

Sends a progress update to the client.

Description

During a slow remote procedure call, call this to inform the client of progress.

Usage

sendProgress(numerator, denominator = 1)

Arguments

numerator

The progress, out of denominator

denominator

What the progress is out of. You could use this for the number of known items to be completed so that each call increases either the numerator (for more items done) and/or the denominator (for more items discovered that need to be done). However, it is not necessary to be so precise; you can set the numerator and denominator however you like on each call as long as it makes sense to the user.

Value

No return value

See Also

sendInfoText for sending text to the user.

Examples

server <- slServer(
  port = 50051,
  interface = list(long_and_complicated = function(x) {
    sendProgress(0,3)
    # First part of work that takes some time
    # ...
    sendProgress(1,3)
    # Second part of work that takes some time
    # ...
    sendProgress(2,3)
    # Last part of work that takes some time
    # ...
    sendProgress(3,3)
  })
)
# ...
slStop(server)

JavaScript function

Description

Calls a server function as defined in the server's call to the slServer function.

Arguments

Return Value


JavaScript function

Description

Call this before calling any other ShinyLight function. Returns a promise that resolves (to nothing) when the connection is ready.


JavaScript function

Description

Turns data received from R into a form that can be set into dataentrygrid.js.

Arguments

Return Value

Examples

## Not run: 
t = shinylight.makeTable(data);
grid.init(t.headers, t.rows);

## End(Not run)

JavaScript function

Description

Open another tab with another (possibly remote from this one) instance of shinylight, initializing it with our own data.

Arguments


JavaScript function: Runs an R function.

Description

The R side must be running the slRunRServer function.

Arguments

Return Value


JavaScript function

Description

Sets the text content of an element (or its value as appropriate) to the JSON representation of an object.

Arguments


JavaScript function: Sets an <img> element to display a plot returned by runR.

Description

Normally you do not need to call this because to get shinylight to produce a plot you need to set the plotElement argument, and doing so will cause this element to receive the plot automatically.

Arguments


JavaScript function

Description

Sets the text content of an element (or its value as appropriate).

Arguments


JavaScript function

Description

Sets a dataentrygrid object to the result of runR, if appropriate.

Arguments


JavaScript function

Description

Sets a dataentrygrid object to the result of runR. The object will have fixed rows, with names derived from the row names in the original data frame.

Arguments


Start a ShinyLight server which runs R that it is sent

Description

Start a ShinyLight server which runs R that it is sent

Usage

slRunRServer(
  permittedSymbols,
  appDir = NULL,
  host = "127.0.0.1",
  port = NULL,
  daemonize = FALSE,
  initialize = NULL
)

Arguments

permittedSymbols

List of symbols that are permitted in the R commands passed. Remember to include data, $ and <-.

appDir

Directory containing files to serve (for example system.file("www", package = "your-package"))

host

IP address to listen on, default is "127.0.0.1" (localhost). Use "0.0.0.0" to run in a docker container.

port

Internet port of the virtual server. If not defined, a random free port will be chosen and the browser will be opened to show the GUI.

daemonize

If TRUE, keep serving forever without returning. This is useful when called from RScript, to keep

initialize

A json string or list (that will be converted to a JSON string) to be passed to the JavaScript as initial data. The index.html must contain a line containing var shinylight_initial_data=, which will be replaced with code that sets shinylight_initial_data to this supplied JSON string.

Value

server object, unless daemonize is TRUE.

See Also

slServer for the more general form of this function, or slStop to stop a running server. shinylight.runR is the JavaScript function you need to call to pass R code from the browser to the server.

Examples

server <- slRunRServer(
  permitted = list("*"),
  port = 50053
)
# Normally we would use shinylight.js to send the function over
# and receive the result, not R and websocket.
ws <- websocket::WebSocket$new("ws://127.0.0.1:50053/x")
resultdata <- NULL
ws$onMessage(function(event) {
  resultdata <<- jsonlite::fromJSON(event$data)$result$data
})
ws$onOpen(function(event) {
  ws$send('{"method":"runR","params":{"Rcommand":"3 * 57"}}')
})
timeout = 30
while(is.null(resultdata) && 0 < timeout) {
  later::run_now()
  Sys.sleep(0.1)
  timeout <- timeout - 1
}
ws$close()
slStop(server)
stopifnot(resultdata == 171)  # 3 * 57 == 171
grDevices::png()  # workaround; you do not have to do this

Start a ShinyLight server

Description

Start a ShinyLight server

Usage

slServer(
  interface,
  appDir = NULL,
  host = "127.0.0.1",
  port = NULL,
  daemonize = FALSE,
  initialize = NULL
)

Arguments

interface

List of functions you want to be able to call from the browser. If you want to use the Shinylight Framework, this should have one member getSchema. For details of this, see the documentation for [shinylightFrameworkStart].

appDir

Directory containing files to serve (for example system.file("www", package = "your-package"))

host

IP address to listen on, default is "127.0.0.1" (localhost). Use "0.0.0.0" to run in a docker container.

port

Internet port of the virtual server. If not defined, a random free port will be chosen and the browser will be opened to show the GUI.

daemonize

If TRUE, keep serving forever without returning. This is useful when called from RScript, to keep

initialize

A json string or list (that will be converted to a JSON string) to be passed to the JavaScript as initial data. For non-framework apps, the index.html must contain a line containing var shinylight_initial_data=, which will be replaced with code that sets shinylight_initial_data to this supplied JSON string.

Value

server object, unless daemonize is TRUE in which case the function will not return.

See Also

slStop to stop a running server, and slRunRServer to run a server that just accepts R code.

Examples

# You can leave out port and daemonize to launch a browser
# pointing at your server
server <- slServer(
  port = 50052,
  interface = list(
    multiply = function(x, y) { x * y }
  )
)
# Normally we would use shinylight.js to send the function over
# and receive the result, not R and websocket.
ws <- websocket::WebSocket$new("ws://127.0.0.1:50052/x")
resultdata <- NULL
ws$onMessage(function(event) {
  resultdata <<- jsonlite::fromJSON(event$data)$result$data
})
ws$onOpen(function(event) {
  ws$send('{ "method": "multiply", "params": { "x": 3, "y": 47 } }')
})
timeout = 30
while(is.null(resultdata) && 0 < timeout) {
  later::run_now()
  Sys.sleep(0.1)
  timeout <- timeout - 1
}
ws$close()
slStop(server)
stopifnot(resultdata == 141)  # multiply(3, 47) == 141
grDevices::png()  # workaround; you do not have to do this

Stops a ShinyLight GUI

Description

Stops a ShinyLight GUI

Usage

slStop(server = NULL)

Arguments

server

The server (returned by slServer or slRunRServer) to stop. If not supplied all servers will be stopped.

Value

No return value

Examples

server <- slServer(
  port = 50051,  # leave this out if you don't care about the port number
  interface = list(
    multiply = function(x, y) { x * y }
  )
)
# ...
slStop(server)

JavaScript class: A monkey-patched HTMLElement.

Description

A Container Element is an element for displaying a set of controls and their labels.

Properties

makeSubElement

function Gets an element in which a control and its label can be stored. You do not need to call this unless you have made your own custom control; it will be called by functions such as toolkit.paramText. Pass in the ID of the control (you will need the ID for the getData and setData calls).

getData

function Returns an object mapping contained controls (or nested containers) to their current values.

setData

function Sets the values of the contained controls. data is a mapping from the IDs of the contained controls to the data that should be set on them.

See Also

toolkit.stack

toolkit.banner

toolkit.optionsPage


JavaScript class

Description

A container for a single control.

Properties

addElement

function Adds an element. Should be called once with a control's label, and then again with the control itself.

See Also

toolkit.HTMLContainerElement


JavaScript class

Description

A monkey-patched HTMLElement representing a control with its label.

Properties

getData

function Returns the current displayed value.

setData

function Sets the value.

hide

function Makes the element invisible and non-interactive

show

function makes the element visible and (potentially) interactive

See Also

toolkit.paramBoolean

toolkit.paramColor

toolkit.paramFloat

toolkit.paramInteger

toolkit.paramSelector

toolkit.paramText


JavaScript class: A monkey-patched HTMLElement with some extra methods.

Description

Certain elements returned by Toolkit methods are Positioned Elements. It is necessary for elements in some places in the document to be Positioned Elements for the document resizing and formatting to work.

If you have an HTML element that is not a Positioned Element that you want to add to a place where only Positioned Elements are required, wrap it in toolkit.scrollingWrapper or toolkit.nonScrollingWrapper.

Properties

setSize

function Sets the position of the element on the document in pixels, with parameters for left, top, width and height in that order.

getSize

function Returns an object with members left, top, width and height for the position of the element.

hide

function Makes the element invisible and non-interactive

show

function makes the element visible and (potentially) interactive


JavaScript function: Finds if a predicate is true for all members of an array or object.

Description

Calls a function for each member of an array or object until either one of them returns false (in which case all returns false) or we run out of elements (in which case all returns true).

Arguments


JavaScript function: Finds if a predicate is true for any member of an array or object.

Description

Calls a function for each member of an array or object until either one of them returns true (in which case any returns true) or we run out of elements (in which case any returns false).

Arguments


JavaScript function

Description

Returns a Container Element for displaying controls horizontally.

Arguments

Return Value


JavaScript function: Returns a button.

Description

This button is an HTML element, but it is not an HTML button. Styling and JavaScript provide the button-like look-and-feel.

Arguments

Return Value


JavaScript function: Dereferences an object or array through multiple indices.

Description

deref(o, [a,b,c], d) is a safe way of doing o[a][b][c]. If that path does not exist, d is returned. If d is not supplied, null is returned. Any undefined values in path are ignored.

Arguments

Return Value


JavaScript function: A panel with a smaller footer.

Description

Returns a Positioned Element consisting of a body and a footer.

Arguments

Return Value


JavaScript function

Description

Calls a function for each member of an array or object.

Arguments


JavaScript function: Option group title

Description

Adds a group title to an toolkit.optionsPage.

Arguments


JavaScript function: A panel with a smaller header.

Description

Returns a Positioned Element consisting of a header and a body.

Arguments

Return Value


JavaScript function

Description

An image element.

Arguments

Return Value


JavaScript function: A panel with a side bar.

Description

Returns a Positioned Element consisting of a left side bar and a body.

Arguments

Return Value


JavaScript function: Returns a button that uploads a file from the client.

Description

This button is an HTML element, but it is not an HTML button. Styling and JavaScript provide the button-like look-and-feel.

Arguments

Return Value


JavaScript function: Makes a label suitable for labelling a control.

Description

The label has translatable text and a help tooltip (if translated for).

Arguments

Return Value


JavaScript function: Returns a Positioned Element just containing one element.

Description

This element does not gain scrollbars if it is too large for this returned container, and it will try to take up its full size in the layout.

Arguments

Return Value


JavaScript function: Returns a Container Element for displaying controls vertically.

Description

Returns an element with a makeSubElement method that adds elements vertically. This differs from toolkit.stack in that the labels will be aligned on the left and the controls will be aligned on the right. It would make a nice options page, for example.

Return Value


JavaScript function: A panel with an overlay.

Description

Returns a Positioned Element consisting of two elements placed in the same position. To be able to see the lower (main) element you must either call hide() on the overlay, or make it transparent with CSS.

Arguments

Return Value


JavaScript function: Returns a Positioned Element for displaying controls in tabbed pages.

Description

Only one page will be visible at a time. The returned element has getData and setData methods that take or return (respectively) an object with keys that are the IDs of the pages.

Arguments

Return Value


JavaScript function: Returns a checkbox input Toolkit Control.

Description

A control for a boolean value rendered as a checkbox.

Arguments

Return Value


JavaScript function: Returns a colour input Toolkit Control.

Description

It is a standard HTML input control with type color. The value returned is a six-hex-digit string prefixed with a #.

Arguments

Return Value


JavaScript function: Returns a floating point input Toolkit Control.

Description

Values outside the permitted range will gain the "invalid" class, but there is no other effect.

Arguments

Return Value


JavaScript function: Returns an integer input Toolkit Control.

Description

Values outside the permitted range will gain the "invalid" class, but there is no other effect.

Arguments

Return Value


JavaScript function: Returns a custom selection box Toolkit Control.

Description

This is different to a normal selection box because it allows tooltips on the items within the list.

Arguments

Return Value


JavaScript function: Returns a text input Toolkit Control.

Description

Any text is permitted unless a validate function is supplied.

Arguments

Return Value


JavaScript function: A static text Toolkit Control in a preformatted style.

Description

This element is like a control in that it has a label and actual text content, but it is not interactive.

Arguments

Return Value


JavaScript function: Returns a Positioned Element progress bar.

Description

The progress is set by calling the setData() method.

Return Value


JavaScript function: A panel with a side bar.

Description

Returns a Positioned Element consisting of a right side bar and a body.

Arguments

Return Value


JavaScript function: Returns a Positioned Element just containing one element.

Description

This element gains scrollbars if it is too large for this returned container.

Arguments

Return Value


JavaScript function: Replaces the <main> tag in the document with this element.

Description

The element will have its resize event wired up. If el is a Toolkit Positioned Element, it will be resized correctly when the window is resized.

Arguments


JavaScript function: Returns a Container Element for displaying controls vertically.

Description

Returns a Container Element with a makeSubElement method that adds elements vertically, with the labels above the controls they correspond to.

Arguments

Return Value


JavaScript function: A static text Toolkit Control.

Description

This element is like a control in that it has a label and actual text content, but it is not interactive.

Arguments

Return Value


JavaScript function: Left/right panels with a draggable divider.

Description

Returns a Positioned Element with a draggable vertical divider bordering two other Positioned Elements.

Arguments

Return Value


JavaScript function: Transforms a function that should not be called too often into a function that can be called as often as you like.

Description

The returned function can be called as often as you like with whatever arguments you like. If it is called again within ticks ticks (a tick is 100ms), this call is ignored. If it is not called again within this time, the arguments are passed on to the delegate function. In other words, in a string of calls less than ticks x 100ms apart from each other, only the last of these calls actually happens.

Arguments

Return Value


JavaScript function: Adds a fake callback argument to a nullary function.

Description

Perhaps you have a nullary function that you want called when the user clicks a button, but the toolkit.button function wants a unary function that has a completion callback so that the button knows when to pop back up again. In this situation you might wrap your function with a call to toolkit.withTimeout.

Arguments

Return Value