DevExtreme v23.2 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

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
const onButtonClick = (name) => { DevExpress.ui.notify(`The "${name}" button has been clicked`); }; const onSelectionChanged = (name) => { DevExpress.ui.notify(`The "${name}" value has been changed`); }; const onFontFamilyClick = () => { DevExpress.ui.notify('The "Font Family" value has been changed'); }; const onHeadingClick = () => { DevExpress.ui.notify('The "Heading" value has been changed'); }; const toolbarSeparator = { locateInMenu: 'auto', location: 'before', template(itemData, itemIndex, element) { $('<div>') .addClass('toolbar-separator') .appendTo(element); }, menuItemTemplate(itemData, itemIndex, element) { $('<div>') .addClass('toolbar-menu-separator') .appendTo(element); }, }; const toolbarItems = [ { location: 'before', widget: 'dxButton', options: { icon: 'undo', onClick() { onButtonClick('Undo'); }, }, }, { location: 'before', widget: 'dxButton', options: { icon: 'redo', onClick() { onButtonClick('Redo'); }, }, }, toolbarSeparator, { location: 'before', locateInMenu: 'auto', widget: 'dxDropDownButton', options: { width: '100%', displayExpr: 'text', keyExpr: 'size', useSelectMode: true, items: fontSizes, selectedItemKey: 14, itemTemplate(itemData) { return $('<div>') .text(itemData.text) .css('font-size', `${itemData.size}px`); }, onSelectionChanged() { onSelectionChanged('Font Size'); }, }, }, { location: 'before', locateInMenu: 'auto', widget: 'dxDropDownButton', options: { width: '100%', icon: 'indent', displayExpr: 'text', keyExpr: 'lineHeight', useSelectMode: true, items: lineHeights, selectedItemKey: 1.35, onSelectionChanged() { onSelectionChanged('Line Height'); }, }, }, { locateInMenu: 'auto', location: 'before', widget: 'dxSelectBox', options: { placeholder: 'Font', displayExpr: 'text', dataSource: fontFamilies, inputAttr: { 'aria-label': 'Font' }, onItemClick() { onFontFamilyClick(); }, }, }, toolbarSeparator, { location: 'before', widget: 'dxButtonGroup', options: { displayExpr: 'text', items: fontStyles, keyExpr: 'icon', stylingMode: 'outlined', selectionMode: 'multiple', onItemClick(e) { onButtonClick(e.itemData.hint); }, }, }, { location: 'before', template(itemData, itemIndex, element) { $(element).addClass('toolbar-separator'); }, }, { locateInMenu: 'auto', location: 'before', widget: 'dxButtonGroup', template(itemData, itemIndex, element) { const $buttonGroup = $('<div>').dxButtonGroup({ items: textAlignItems, keyExpr: 'alignment', stylingMode: 'outlined', selectedItemKeys: ['left'], onItemClick(e) { onButtonClick(e.itemData.hint); }, }); $buttonGroup.appendTo(element); }, menuItemTemplate(itemData, itemIndex, element) { const $buttonGroup = $('<div>').dxButtonGroup({ displayExpr: 'text', items: textAlignItemsExtended, keyExpr: 'alignment', stylingMode: 'outlined', selectedItemKeys: ['left'], onItemClick(e) { onButtonClick(e.itemData.hint); }, }); $buttonGroup.appendTo(element); }, }, { location: 'before', widget: 'dxButtonGroup', options: { items: listTypes, keyExpr: 'alignment', stylingMode: 'outlined', onItemClick(e) { onButtonClick(e.itemData.hint); }, }, }, toolbarSeparator, { locateInMenu: 'auto', location: 'before', widget: 'dxSelectBox', options: { displayExpr: 'text', valueExpr: 'text', value: headings[0].text, dataSource: headings, inputAttr: { 'aria-label': 'Text Style' }, onItemClick() { onHeadingClick(); }, }, }, toolbarSeparator, { location: 'before', locateInMenu: 'auto', widget: 'dxButton', showText: 'inMenu', options: { icon: 'link', text: 'Link', onClick() { onButtonClick('Link'); }, }, }, { location: 'before', locateInMenu: 'auto', widget: 'dxButton', showText: 'inMenu', options: { icon: 'image', text: 'Add image', onClick() { onButtonClick('Add Image'); }, }, }, toolbarSeparator, { location: 'before', locateInMenu: 'auto', widget: 'dxButton', showText: 'inMenu', options: { icon: 'clearformat', text: 'Clear formating', onClick() { onButtonClick('Clear Formating'); }, }, }, { location: 'before', locateInMenu: 'auto', widget: 'dxButton', showText: 'inMenu', options: { icon: 'codeblock', text: 'Code block', onClick() { onButtonClick('Code Block'); }, }, }, { location: 'before', locateInMenu: 'auto', widget: 'dxButton', showText: 'inMenu', options: { icon: 'blockquote', text: 'Blockquote', onClick() { onButtonClick('Blockquote'); }, }, }, toolbarSeparator, { location: 'after', widget: 'dxButton', showText: 'inMenu', options: { icon: 'attach', text: 'Attach', onClick() { onButtonClick('Attach'); }, }, }, { locateInMenu: 'always', widget: 'dxButton', showText: 'inMenu', options: { icon: 'help', text: 'About', onClick() { onButtonClick('About'); }, }, }, ]; $(() => { $('#resizable-container').dxResizable({ minWidth: 500, minHeight: 150, maxHeight: 370, handles: 'right', area: '.widget-container', }); const toolbar = $('#toolbar').dxToolbar({ dataSource: toolbarItems, multiline: true, }).dxToolbar('instance'); $('#toolbar-mode').dxCheckBox({ value: true, text: 'Multiline mode', onValueChanged(e) { toolbar.option('multiline', e.value); }, }); });
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <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" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script>window.jQuery || document.write(decodeURIComponent('%3Cscript src="js/jquery.min.js"%3E%3C/script%3E'))</script> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/23.2.5/css/dx.light.css" /> <script src="js/dx.all.js"></script> <script src="data.js"></script> <link rel="stylesheet" type="text/css" href="styles.css" /> <script src="index.js"></script> </head> <body class="dx-viewport"> <div class="demo-container"> <div class="widget-container"> <div id="resizable-container" class="resizable-container"> <div id="toolbar"></div> </div> </div> <div class="options-container"> <div class="caption">Options</div> <div id="toolbar-mode"></div> </div> </div> </body> </html>
.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: 10px; } .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; }
const fontSizes = [ { size: 10, text: '10px' }, { size: 12, text: '12px' }, { size: 14, text: '14px' }, { size: 16, text: '16px' }, { size: 18, text: '18px' }, ]; const lineHeights = [ { lineHeight: 1, text: '1' }, { lineHeight: 1.35, text: '1.35' }, { lineHeight: 1.5, text: '1.5' }, { lineHeight: 2, text: '2' }, ]; const fontFamilies = [ { text: 'Arial' }, { text: 'Courier New' }, { text: 'Georgia' }, { text: 'Impact' }, { text: 'Lucida Console' }, { text: 'Tahoma' }, { text: 'Times New Roman' }, ]; const headings = [ { text: 'Normal text' }, { text: 'Heading 1' }, { text: 'Heading 2' }, { text: 'Heading 3' }, { text: 'Heading 4' }, { text: 'Heading 5' }, ]; const fontStyles = [ { icon: 'bold', hint: 'Bold', }, { icon: 'italic', hint: 'Italic', }, { icon: 'underline', hint: 'Underlined', }, { icon: 'strike', hint: 'Strikethrough', }, ]; 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', }, ]; const textAlignItems = textAlignItemsExtended.map((item) => { const { icon, alignment, hint } = item; return { icon, alignment, hint, }; }); const listTypes = [ { icon: 'orderedlist', alignment: 'orderedlist', hint: 'Ordered', }, { icon: 'bulletlist', alignment: 'bulletlist', hint: 'Bullet', }, ];