Your search did not match any results.
Toolbar

Adaptability

This demo demonstrates how the DevExtreme Toolbar component can adapt itself to different screen widths.

If you would like to learn more about our feature-complete Toolbar component, please refer to the following tutorial: Getting Started with Toolbar.

In this demo, you can drag our Toolbar container's resizing handle to visualize resize operations and view our rendering implementation on different screens. When used in single-line mode (default), our Toolbar does not wrap content and displays an overflow menu for items that do not fit within the container. Use the locateInMenu property to control whether items appear in the overflow menu.

If Toolbar width exceeds container width (and if you enable the component’s multiline property), our Toolbar wraps content across multiple lines.

Backend API
Copy to CodeSandBox
Apply
Reset
<template> <div> <div class="widget-container"> <DxResizable class="resizable-container" area=".widget-container" handles="right" :min-width="500" :min-height="150" :max-height="370" > <DxToolbar :multiline="multiline"> <DxItem location="before" widget="dxButton" > <DxButton icon="undo" :on-click="onUndoButtonClick" /> </DxItem> <DxItem location="before" widget="dxButton" > <DxButton icon="redo" :on-click="onRedoButtonClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" template="separatorTemplate" menu-item-template="menuSeparatorTemplate" /> <DxItem location="before" locate-in-menu="auto" > <DxDropDownButton width="100%" display-expr="text" key-expr="size" item-template="fontSizeTemplate" :use-select-mode="true" :items="fontSizes" :selected-item-key="fontSize" :on-selection-changed="onFontSizeSelectionChanged" > <template #fontSizeTemplate="{ data }"> <div :style="{ fontSize: data.size + 'px' }"> {{ data.text }} </div> </template> </DxDropDownButton> </DxItem> <DxItem location="before" locate-in-menu="auto" > <DxDropDownButton width="100%" icon="indent" display-expr="text" key-expr="lineHeight" :use-select-mode="true" :items="lineHeights" :selected-item-key="lineHeight" :on-selection-changed="onLineHeightSelectionChanged" /> </DxItem> <DxItem location="before" locate-in-menu="auto" > <DxSelectBox placeholder="Font" display-expr="text" :data-source="fontFamilies" :on-item-click="onFontFamilyClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" template="separatorTemplate" menu-item-template="menuSeparatorTemplate" /> <DxItem location="before"> <DxButtonGroup display-expr="text" key-expr="icon" styling-mode="outlined" selection-mode="multiple" :items="fontStyles" :on-item-click="onFontStyleItemClick" /> </DxItem> <DxItem location="before" template="separatorTemplate" /> <DxItem location="before" locate-in-menu="auto" template="textAlignTemplate" menu-item-template="textAlignMenuTemplate" widget="dxButtonGroup" /> <DxItem location="before"> <DxButtonGroup key-expr="alignment" styling-mode="outlined" :items="listTypes" :on-item-click="onListTypeButtonClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" template="separatorTemplate" menu-item-template="menuSeparatorTemplate" /> <DxItem location="before" locate-in-menu="auto" > <DxSelectBox display-expr="text" value-expr="text" :data-source="headings" :value="heading" :on-item-click="onHeadingClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" template="separatorTemplate" menu-item-template="menuSeparatorTemplate" /> <DxItem location="before" locate-in-menu="auto" show-text="inMenu" widget="dxButton" > <DxButton icon="link" text="Link" :on-click="onLinkButtonClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" show-text="inMenu" widget="dxButton" > <DxButton icon="image" text="Add image" :on-click="onAddImageButtonClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" template="separatorTemplate" menu-item-template="menuSeparatorTemplate" /> <DxItem location="before" locate-in-menu="auto" show-text="inMenu" widget="dxButton" > <DxButton icon="clearformat" text="Clear formating" :on-click="onClearButtonClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" show-text="inMenu" widget="dxButton" > <DxButton icon="codeblock" text="Code block" :on-click="onCodeBlockButtonClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" show-text="inMenu" widget="dxButton" > <DxButton icon="blockquote" text="Blockquote" :on-click="onQuoteButtonClick" /> </DxItem> <DxItem location="before" locate-in-menu="auto" template="separatorTemplate" menu-item-template="menuSeparatorTemplate" /> <DxItem location="after" widget="dxButton" show-text="inMenu" > <DxButton icon="attach" text="Attach" :on-click="onAttachButtonClick" /> </DxItem> <DxItem locate-in-menu="always" widget="dxButton" show-text="inMenu" > <DxButton icon="help" text="About" :on-click="onAboutButtonClick" /> </DxItem> <template #separatorTemplate> <div class="toolbar-separator"/> </template> <template #menuSeparatorTemplate> <div class="toolbar-menu-separator"/> </template> <template #textAlignTemplate> <DxButtonGroup key-expr="alignment" styling-mode="outlined" :items="textAlignItems" :selected-item-keys="textAlign" @item-click="onTextAlignItemClick" /> </template> <template #textAlignMenuTemplate> <DxButtonGroup :items="textAlignItemsExtended" display-expr="text" :selected-item-keys="textAlign" key-expr="alignment" styling-mode="outlined" @item-click="onTextAlignItemClick" /> </template> </DxToolbar> </DxResizable> </div> <div class="options-container"> <div class="caption">Options</div> <DxCheckBox v-model="multiline" text="Multiline mode" /> </div> </div> </template> <script> import DxCheckBox from 'devextreme-vue/check-box'; import DxToolbar, { DxItem } from 'devextreme-vue/toolbar'; import DxButton from 'devextreme-vue/button'; import DxButtonGroup from 'devextreme-vue/button-group'; import DxResizable from 'devextreme-vue/resizable'; import DxDropDownButton from 'devextreme-vue/drop-down-button'; import DxSelectBox from 'devextreme-vue/select-box'; import notify from 'devextreme/ui/notify'; import { fontSizes, lineHeights, fontFamilies, fontStyles, headings, textAlignItems, textAlignItemsExtended, listTypes, } from './data.js'; import 'devextreme/ui/select_box'; const lineHeightDefault = lineHeights[1].lineHeight; const textAlignDefault = [textAlignItems[0].alignment]; const fontSizeDefault = fontSizes[2].size; const headingDefault = headings[0].text; export default { components: { DxCheckBox, DxToolbar, DxButton, DxButtonGroup, DxItem, DxResizable, DxDropDownButton, DxSelectBox, }, data() { return { multiline: true, lineHeight: lineHeightDefault, textAlign: textAlignDefault, fontSize: fontSizeDefault, heading: headingDefault, fontSizes, lineHeights, fontFamilies, fontStyles, listTypes, headings, }; }, computed: { textAlignItems() { return textAlignItems; }, textAlignItemsExtended() { return textAlignItemsExtended; }, }, methods: { onTextAlignItemClick(e) { const { alignment, hint } = e.itemData; this.textAlign = alignment; this.onButtonClick(hint); }, onButtonClick(name) { notify(`The "${name}" button has been clicked`); }, onUndoButtonClick() { this.onButtonClick('Undo'); }, onRedoButtonClick() { this.onButtonClick('Redo'); }, onFontStyleItemClick(e) { this.onButtonClick(e.itemData.hint); }, onListTypeButtonClick(e) { this.onButtonClick(e.itemData.hint); }, onLinkButtonClick() { this.onButtonClick('Link'); }, onAddImageButtonClick() { this.onButtonClick('Add Image'); }, onClearButtonClick() { this.onButtonClick('Clear Formating'); }, onCodeBlockButtonClick() { this.onButtonClick('Code Block'); }, onQuoteButtonClick() { this.onButtonClick('Blockquote'); }, onAttachButtonClick() { this.onButtonClick('Attach'); }, onAboutButtonClick() { this.onButtonClick('About'); }, onSelectionChanged(name) { notify(`The "${name}" value has been changed`); }, onFontSizeSelectionChanged() { this.onSelectionChanged('Font Size'); }, onLineHeightSelectionChanged() { this.onSelectionChanged('Line Height'); }, onHeadingClick() { notify('The "Heading" value has been changed'); }, onFontFamilyClick() { notify('The "Font Family" value has been changed'); }, }, }; </script> <style> .dx-resizable-handle::after { content: ""; position: absolute; width: 9px; height: 36px; border: none; border-radius: 50px; background-color: #fff; box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.24); } .dx-resizable-handle-right::after { top: 50%; right: -5px; transform: translateY(-50%); } .dx-toolbar.dx-toolbar-multiline .dx-toolbar-item { margin-bottom: 5px; } .widget-container { margin-right: 6px; } .resizable-container { padding: 10px; height: 300px; border: 1px dotted #999; border-radius: 4px; box-sizing: border-box; } .options-container { margin-top: 20px; padding: 20px; background-color: rgba(191, 191, 191, 0.15); position: relative; } .caption { font-size: 18px; font-weight: 500; margin-bottom: 10px; } .toolbar-separator { height: 36px; margin: 0 5px; border-left: 1px solid #ddd; } .toolbar-menu-separator { height: 1px; border-bottom: 1px solid #ddd; } </style>
import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app');
<!DOCTYPE html> <html> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/22.2.6/css/dx.light.css" /> <script src="https://unpkg.com/core-js@2.6.12/client/shim.min.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import("./index.js"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"> </div> </div> </body> </html>
export const fontSizes = [ { size: 10, text: '10px' }, { size: 12, text: '12px' }, { size: 14, text: '14px' }, { size: 16, text: '16px' }, { size: 18, text: '18px' }, ]; export const lineHeights = [ { lineHeight: 1, text: '1' }, { lineHeight: 1.35, text: '1.35' }, { lineHeight: 1.5, text: '1.5' }, { lineHeight: 2, text: '2' }, ]; export const fontFamilies = [ { text: 'Arial' }, { text: 'Courier New' }, { text: 'Georgia' }, { text: 'Impact' }, { text: 'Lucida Console' }, { text: 'Tahoma' }, { text: 'Times New Roman' }, ]; export const headings = [ { text: 'Normal text' }, { text: 'Heading 1' }, { text: 'Heading 2' }, { text: 'Heading 3' }, { text: 'Heading 4' }, { text: 'Heading 5' }, ]; export const fontStyles = [ { icon: 'bold', hint: 'Bold', }, { icon: 'italic', hint: 'Italic', }, { icon: 'underline', hint: 'Underlined', }, { icon: 'strike', hint: 'Strikethrough', }, ]; export const textAlignItemsExtended = [ { icon: 'alignleft', alignment: 'left', hint: 'Align Left', text: 'Align left', }, { icon: 'aligncenter', alignment: 'center', hint: 'Center', text: 'Center', }, { icon: 'alignright', alignment: 'right', hint: 'Align Right', text: 'Align right', }, { icon: 'alignjustify', alignment: 'justify', hint: 'Justify', text: 'Justify', }, ]; export const textAlignItems = textAlignItemsExtended.map((item) => { const { icon, alignment, hint } = item; return { icon, alignment, hint, }; }); export const listTypes = [ { icon: 'orderedlist', alignment: 'orderedlist', hint: 'Ordered', }, { icon: 'bulletlist', alignment: 'bulletlist', hint: 'Bullet', }, ];
window.config = { transpiler: 'plugin-babel', meta: { '*.vue': { loader: 'vue-loader', }, 'devextreme/localization.js': { 'esModule': true, }, }, paths: { 'npm:': 'https://unpkg.com/', }, map: { 'vue': 'npm:vue@3.2.47/dist/vue.esm-browser.js', 'vue-loader': 'npm:dx-systemjs-vue-browser@1.0.15/index.js', 'mitt': 'npm:mitt/dist/mitt.umd.js', 'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.28.0/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@22.2.6/cjs', 'devextreme-vue': 'npm:devextreme-vue@22.2.6', 'jszip': 'npm:jszip@3.7.1/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@1.5.20/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.1.72/dist/dx-diagram.js', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.43/dist/dx-gantt.js', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.11', 'inferno': 'npm:inferno@7.4.11/dist/inferno.min.js', 'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js', 'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js', 'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js', 'inferno-hydrate': 'npm:inferno-hydrate@7.4.11/dist/inferno-hydrate.min.js', 'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js', 'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js', 'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js', 'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js', // Prettier 'prettier/standalone': 'npm:prettier@2.8.4/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.4/parser-html.js', }, packages: { 'devextreme-vue': { main: 'index.js', }, 'devextreme': { defaultExtension: 'js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.11/inferno/package.json', ], babelOptions: { sourceMaps: false, stage0: true, }, }; System.config(window.config);