Skip to main content

Toolbar Widget

The Toolbar widget is a component used for creating button and icon panels in web applications.

It allows developers to easily integrate interactive toolbars into their user interfaces.

The widget is licensed under the MIT license.

Quick start

First steps

To start with the widget, add the necessary package to your project first.

npm install wx-svelte-core
npm install wx-svelte-toolbar

or

yarn add wx-svelte-core
yarn add wx-svelte-toolbar

Now, import the widget into your project.

<script>
import { Willow } from 'wx-svelte-core';
import { Toolbar } from 'wx-svelte-toolbar';
</script>

<Willow>
<Toolbar />
</Willow>

The Willow component is a default theme wrapper that adds necessary styles for all SVAR widgets. The Toolbar component may work without it, but it will not have any styles, and it will be necessary to add them manually. It is a common approach to add the Willow tag once at the top level of the application.

Full init code

To see the widget in action, add some items to the toolbar.

<script>
import { Toolbar } from "wx-svelte-toolbar";

const items = [
{ id: "label", text: "My App" },
{ comp: "spacer" },
{
id: "search",
comp: "button",
icon: "wxi-search",
css: "right",
},
];

function handler(ev) {
console.log(`item ${ev.id} was clicked`);
}
</script>

<Toolbar {items} onclick={handler} />

Visual Themes

The widget is provided in two visual styles - Light and Dark, which are controlled by the theme tag.

<script>
import { Willow, WillowDark } from "wx-svelte-core";
</script>

<!-- Light -->
<Willow>
<Toolbar />
</Willow>

<!-- Dark -->
<WillowDark>
<Toolbar />
</WillowDark>

Defining Toolbar Elements

The toolbar widget provides the ability to include various components, such as buttons, icons, labels, and form elements. These components can be configured and customized to suit specific application needs. Below are examples demonstrating how to define different components in the toolbar.

Adding a Button to the Toolbar

<script>
let items = [
{
id: "search",
comp: "button",
icon: "wxi-search",
css: "right",
handler: onClick,
},
];
</script>

<Toolbar {items} />

Buttons are suitable for triggering actions or events, such as submitting forms or performing searches. The id uniquely identifies the button, comp specifies the type as "button", and icon adds a predefined icon. The optional css parameter can control the button's alignment, and handler assigns a function for handling click events.

Adding an Icon to the Toolbar

<Toolbar items={[{ comp: "icon", icon: "wxi-search" }]} />

Icons can be used to display visual cues or shortcuts. The comp property defines the component type as "icon", and icon assigns the specific visual representation. This is useful for adding static icons without additional functionality.

Adding a Label to the Toolbar

<Toolbar items={[{ text: "My App" }]} />

Labels are ideal for displaying static text, such as the application name or section titles. The text property holds the displayed text content.

Adding a Checkbox to the Toolbar

<script>
import { Checkbox } from "wx-svelte-core";
</script>

<Toolbar items={[{ id: "check", comp: Checkbox }]} values={{ check: true }} />

Checkboxes are used for binary choices, such as toggling features on or off. The comp property specifies the Checkbox component, and values provides the initial checked state.

Adding a Combo Box to the Toolbar

<script>
import { Combo } from "wx-svelte-core";
</script>

<Toolbar
items={[
{
id: "lead",
comp: Combo,
options: [
{ id: 1, label: "Kristina" },
{ id: 2, label: "Dorian" },
],
},
]}
values={{ lead: 1 }}
/>

Combo boxes allow users to select a value from a dropdown list. The comp property references the Combo component, and options defines the selectable items. The values property sets the initial selection.

Adding a Datepicker to the Toolbar

<script>
import { Datepicker } from "wx-svelte-core";
</script>

<Toolbar items={[{ id: "date", comp: Datepicker }]} values={{ date: new Date() }} />

Datepickers enable users to select dates. The comp property specifies the Datepicker component, and values sets the default date.

Adding a Radio Group to the Toolbar

<script>
import { RadioGroup } from "wx-svelte-core";
</script>

<Toolbar
items={[
{
id: "radio",
comp: RadioGroup,
options: [
{ id: 1, label: "Kristina" },
{ id: 2, label: "Dorian" },
],
},
]}
values={{ radio: 1 }}
/>

Radio groups are ideal for selecting a single option from multiple choices. The comp references the RadioGroup component, and options defines the available choices. The values property determines the default selection.

Adding a Richselect to the Toolbar

<script>
import { Richselect } from "wx-svelte-core";
</script>

<Toolbar
items={[
{
id: "lead",
comp: { Richselect },
options: [
{ id: 1, label: "Kristina" },
{ id: 2, label: "Dorian" },
],
},
]}
values={{ lead: 1 }}
/>

Richselect components are advanced dropdowns with enhanced styling and interaction. The comp specifies Richselect, and options provides the dropdown items. The values sets the initial selected item.

Adding a Slider to the Toolbar

<script>
import { Slider } from "wx-svelte-core";
</script>

<Toolbar
items={[{ id: "limit", comp: Slider, min: 2, max: 20 }]}
values={{ limit: 10 }}
/>

Sliders are used for selecting values within a range. The comp references the Slider component, min and max define the range, and values sets the initial value.

Adding a Text Input to the Toolbar

<script>
import { Text } from "wx-svelte-core";
</script>

<Toolbar items={[{ id: "name", comp: Text }]} values={{ name: "John" }} />

Text inputs allow users to enter text data. The comp specifies the Text component, and values sets the default text. This is useful for capturing user input, such as names or search queries.

Grouping Items

The toolbar widget offers flexible options for grouping items in rows, columns, or a combination of both. This allows developers to organize buttons, icons, and other elements in layouts that fit the application's interface requirements.

Defining a Group of Items in a Row

<Toolbar
items={[
{ label: "My App" },
{
layout: "row",
items: [
{ comp: "icon", id: "add", icon: "wxi-plus" },
{ comp: "icon", id: "edit", icon: "wxi-pencil" },
{ comp: "icon", id: "delete", icon: "wxi-trash" },
],
},
]}
/>

This configuration organizes toolbar items in a horizontal layout. Each icon (add, edit, delete) appears in a single row. It is suitable for cases where users need to access multiple related actions side by side, such as editing or managing items in a list.

Defining a Group of Items in a Column

<Toolbar
items={[
{ label: "My App" },
{
layout: "column",
items: [
{ comp: "icon", id: "add", icon: "wxi-plus" },
{ comp: "icon", id: "edit", icon: "wxi-pencil" },
{ comp: "icon", id: "delete", icon: "wxi-trash" },
],
},
]}
/>

In this example, toolbar items are grouped into a vertical layout. Each icon is displayed one below the other. This layout works well in situations where space is constrained horizontally or when grouping actions in a sidebar.

Creating a Multiline Toolbar

<Toolbar
items={[
{
layout: "column",
items: [
{
layout: "row",
items: [
{
id: "font-family",
comp: "richselect",
},
{
id: "font-size",
comp: "richselect",
},
],
},
{
layout: "row",
items: [
{
id: "font-bold",
comp: "icon",
icon: "wxi-bold",
},
{
id: "font-italic",
comp: "icon",
icon: "wxi-italic",
},
{
id: "font-underline",
comp: "icon",
icon: "wxi-underline",
},
],
},
],
},
]}
/>

This setup creates a toolbar with multiple rows grouped into a column layout. The first row contains dropdowns for font-family and font-size, while the second row includes buttons for text formatting (bold, italic, underline). It is ideal for text editors or similar applications where controls are grouped by functionality.

Mixing Columns and Rows in a Toolbar

<Toolbar
items={[
{ id: "label", text: "My App" },
{
layout: "column",
items: [
{ text: "Actions" },
{
layout: "row",
items: [
{
comp: "icon",
icon: "wxi-search",
},
{
comp: "icon",
icon: "wxi-trash",
},
],
},
],
},
]}
/>

This configuration combines column and row layouts. The top column contains a label and a text item ("Actions"), followed by a row with two icons (search and trash). It is useful for creating toolbars with hierarchical groupings, such as sections with headers and related actions.

Toolbar Layout

Options for organizing and displaying items within the toolbar. These functionalities allow developers to structure toolbar items effectively for better usability and adaptability across different screen sizes.

Adding a Separator Between Toolbar Items

<Toolbar
items={[
{ comp: "icon", icon: "wxi-search" },
{ comp: "separator" },
{ comp: "icon", icon: "wxi-plus" },
]}
/>

Separators are used to create visual divisions between toolbar items. This is useful for grouping related actions or icons, making the interface more organized and easier to navigate. In the above example, a separator is placed between two icons to visually distinguish their functionalities.

Aligning Toolbar Items to the Right

<Toolbar
items={[
{ id: "label", text: "My App" },
{ comp: "spacer" },
{
comp: "icon",
icon: "wxi-search",
css: "right",
},
]}
/>

A spacer component can be used to push items such as icons or buttons to the right side of the toolbar. This approach is commonly applied to balance the layout, for example, placing a logo or title on the left and actionable icons on the right.

Collapsing Button Groups into an Icon on Overflow

<Toolbar
overflow="collapse"
items={[
{
id: "font-family",
comp: "richselect",
},
{
id: "font-size",
comp: "richselect",
},
{
// this group may collapse on overflow
layout: "row",
items: [
{
id: "font-bold",
comp: "icon",
icon: "wxi-bold",
},
{
id: "font-italic",
comp: "icon",
icon: "wxi-italic",
},
{
id: "font-underline",
comp: "icon",
icon: "wxi-underline",
},
],
},
]}
/>

When the toolbar cannot display all items due to limited screen space, grouped buttons can collapse into a single icon. This functionality is essential for creating responsive toolbars that adapt to smaller screens. Groups should be defined with a layout: "row" block to enable this behavior. For collapsing the entire toolbar, all items should be wrapped in a top-level row block.

Wrapping Toolbar Items to the Next Line on Overflow

<Toolbar overflow="wrap" />

The default behavior of the toolbar is to wrap items to the next line when there is not enough space. This approach works well for toolbars that need to display all items without hiding or collapsing them, ensuring visibility at all times.

Moving Overflow Items into a Popup Menu

<Toolbar overflow="menu" />

Items that cannot fit into the visible toolbar can be moved into a popup menu. This is useful for reducing visual clutter while still providing access to all toolbar options. The overflow menu is particularly effective in scenarios where a clean appearance is prioritized.

The widget allows for the management of controls in a popup menu by enabling the grouping of elements and customizing the appearance of the popup container. It provides flexibility in organizing and styling toolbar components.

Moving Controls to a Popup Panel

By grouping controls into a "collapsed" layout, these controls are hidden by default and represented by an icon. Clicking the icon expands the group into a popup menu, displaying its content. This feature is useful for organizing toolbar items when screen space is limited or to improve accessibility by grouping related actions.

<Toolbar
items={[
{ id: "label", text: "My App" },
{
layout: "row",
collapsed: true,
icon: "wxi-group",
text: "Actions",
items: [
{
comp: "icon",
icon: "wxi-search",
},
{
comp: "icon",
icon: "wxi-trash",
},
],
},
]}
/>

In this example, the toolbar includes a label "My App" and a collapsed group labeled "Actions". The group is represented by the "wxi-group" icon. When clicked, it displays two actions: a search icon ("wxi-search") and a trash icon ("wxi-trash"). This setup is beneficial for creating a clean and compact toolbar while still providing access to essential tools.

Defining a CSS Class for the Popup Menu Container

A custom CSS class can be applied to the top container of the popup menu to modify its appearance. This is helpful when the default styling does not meet the design requirements, allowing for a tailored look and feel.

<script>
</script>

<Toolbar cssMenu="somemenu" />

<style>
.somemenu {
background-color: #f0f0f0;
}
</style>

In this snippet, the cssMenu property is used to assign the "somemenu" class to the popup menu container. The associated CSS rule changes the background color of the popup menu to a light gray (#f0f0f0). This technique is practical for aligning the popup menu's appearance with the overall application theme or branding.

Event Handling

The Toolbar widget provides methods to detect and respond to user interactions with its controls. Developers can use these methods to handle changes in control values and detect when specific controls are clicked.

Detecting Changes in Control Values

This feature allows tracking when a user modifies the value of a control, such as a text input field. It is useful for scenarios like form building or data entry applications, where immediate feedback or processing is required upon value changes.

<script>
const items = [
{ id: "name", comp: Text },
{ id: "email", comp: Text },
];
function handler(ev) {
const { item, value } = ev;
console.log("changed control", item.id);
console.log("new value", value);
}
</script>

<Toolbar {items} onchange={handler} />

In this example, the items array defines two controls with IDs name and email, both using the Text component. The onchange event is triggered whenever the value of a control changes. The handler function receives an event object containing the item (the control) and the new value. This information is logged to the console, but it can be used for further processing or validation.

Detecting Clicks on Controls

This functionality is used to capture user clicks on controls, such as buttons. It is commonly applied in interactive toolbars where actions need to be performed when a button is pressed.

<script>
const items = [
{ id: "name", comp: "button" },
{ id: "email", comp: "button" },
];
function handler(ev) {
const { item } = ev;
console.log("clicked control", item.id);
}
</script>

<Toolbar {items} onclick={handler} />

Here, the items array defines two button controls with IDs name and email. The onclick event is triggered when a user clicks on any of these buttons. The handler function receives an event object containing the item (the control that was clicked). The control's ID is logged to the console, enabling developers to identify which button was clicked and execute corresponding actions.

Custom Components

The toolbar widget allows developers to extend its functionality by creating and integrating custom components. These components can be registered and utilized to create customized toolbar elements, such as buttons or input fields, tailored to specific application needs.

Registering a Custom Component as a Toolbar Element

Developers can register custom components as toolbar elements to enhance the toolbar's functionality. This feature is useful when creating reusable components that can be referenced across toolbars.

<script>
import { Toolbar, registerToolbarItem } from "wx-svelte-toolbar";
import { Text } from "wx-svelte-core";

// register custom component
registerToolbarItem("text", Text);
</script>

<Toolbar
items={[
{ id: "label", text: "Toolbar with text input" },
{ id: "search", comp: "text" },
]}
/>

In this case, the Text component is registered with the identifier "text". Once registered, the component can be used in the items array of the Toolbar by specifying its identifier in the comp property. This approach allows the inclusion of predefined or externally created components seamlessly in the toolbar.

Creating a Custom Button Control for the Toolbar

Custom button controls can be created to enhance user interaction within the toolbar. This functionality is helpful for buttons with specific styles or behaviors.

Definition in myControl.svelte

<script>
export let menu;
export let text;
</script>

<button class:menu onclick>{text}</button>

<style>
.menu {
font-weight: bold;
}
</style>

This custom button component accepts two properties:

  • menu, which determines if the button is part of a popup menu (true when inside a menu).
  • text, which specifies the button's label.

The button emits an onclick event when clicked. The menu property is used to apply additional styles, as demonstrated by the menu class.

Usage in App.svelte

<script>
import { Toolbar, registerToolbarItem } from "wx-svelte-toolbar";
import MyControl from "./MyControl.svelte";

// register custom component
registerToolbarItem("cb", Text);
</script>

<Toolbar
items={[
{ id: "label", text: "Toolbar with custom button" },
{ id: "search", comp: "cb" },
]}
/>

Here, the custom button is registered with the identifier "cb" and included in the toolbar by referencing it in the items array. Additional properties can be added to the item object and will be accessible in the custom button component.

Creating a Custom Input Control for the Toolbar

Custom input controls can be created to allow data entry directly within the toolbar. This is useful for search fields, text inputs, or other editable fields.

Definition in myControl.svelte

<script>
export let value;
export let type = "text";
</script>

<input type="text" bind:value />

This custom input component supports the following:

  • value property, which holds the initial input value and updates the toolbar's state when modified.
  • type property, which defaults to "text" and determines the input type.

Any additional properties defined in the item object will also be accessible in the component.

Usage in App.svelte

<script>
import { Toolbar, registerToolbarItem } from "wx-svelte-toolbar";
import MyControl from "./MyControl.svelte";

// register custom component
registerToolbarItem("ci", Text);
</script>

<Toolbar
items={[
{ id: "label", text: "Toolbar with custom input" },
{ id: "search", comp: "ci", type: "search" },
]}
/>

The custom input control is registered with the identifier "ci". It is then used in the toolbar with properties like type set in the items array. This enables the creation of specialized input fields, such as a search bar.

Toolbar Initialization and Control Management

The toolbar widget allows developers to initialize a customizable toolbar and manage the values of its controls. The following sections explain how to set up the toolbar, retrieve control values, set initial values, and dynamically update control values.

Toolbar Initialization

The toolbar can be initialized with predefined items such as labels, spacers, and buttons. Each item can be customized with properties like id, text, comp (component type), icon, and css classes. Event handling is supported to capture user interactions.

<script>
import { Toolbar } from "wx-svelte-toolbar";

const items = [
{ id: "label", text: "My App" },
{ comp: "spacer" },
{
id: "search",
comp: "button",
icon: "wxi-search",
css: "right",
},
];

function handler(ev) {
console.log(`item ${ev.id} was clicked`);
}
</script>

<Toolbar {items} onclick={handler} />

This setup is useful for creating a toolbar with a combination of static labels, flexible spacers, and interactive buttons. The handler function logs the id of the clicked item, enabling easy tracking of user actions.

Retrieving Current Control Values

The toolbar allows binding to a values object to track the current state of its controls. This can be used to monitor user inputs or selections in real time.

<script>
let values = {};

// will be triggered on changes
$: console.log(JSON.stringify(values));
</script>

<Toolbar
items={[
{ comp: Text, key: "query" },
{ comp: Switch, key: "state" },
]}
bind:values
/>

This functionality is suitable for dynamic interfaces where control states need to be observed and logged. For example, it can be used to capture a search query and a toggle state simultaneously.

Setting Initial Values for Controls

Initial values for toolbar controls can be predefined by passing a values object during initialization. The keys in the values object should match the key properties of the toolbar items.

<script>
const values = { query: "something else", state: true };
</script>

<Toolbar
items={[
{ comp: Text, key: "query" },
{ comp: Switch, key: "state" },
]}
{values}
/>

This feature is especially useful for preloading a toolbar with default settings, such as a predefined search term or an active toggle switch.

Modifying Control Values Dynamically

Control values in the toolbar can be updated programmatically by modifying the values object. This allows developers to reset or change control states based on application logic.

<script>
const items = [
{ type: "label", text: "Active Mode" },
{ comp: Switch, key: "state" },
];

let values = { query: "something else", state: true };

// change value later on
const reset = () => {
values = { ...values, state: false };
};
</script>

<Toolbar {items} {values} />

This capability is ideal for scenarios where controls need to be reset or updated dynamically, such as toggling between different modes or clearing user inputs.