DevExtreme v24.1 is now available.

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

Your search did not match any results.

React 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.

Backend API
import React, { useCallback, useState } from 'react'; import Toolbar, { Item } from 'devextreme-react/toolbar'; import Button from 'devextreme-react/button'; import ButtonGroup, { ButtonGroupTypes } from 'devextreme-react/button-group'; import Resizable from 'devextreme-react/resizable'; import CheckBox from 'devextreme-react/check-box'; import DropDownButton, { DropDownButtonTypes } from 'devextreme-react/drop-down-button'; import SelectBox, { SelectBoxTypes } from 'devextreme-react/select-box'; import themes from 'devextreme/ui/themes'; import notify from 'devextreme/ui/notify'; import 'devextreme/ui/select_box'; import { fontSizes, lineHeights, fontFamilies, fontStyles, headings, textAlignItems, textAlignItemsExtended, listTypes, fontInputAttr, textStyleInputAttr, } from './data.ts'; const stylingMode = !themes.current().startsWith('generic') ? 'text' : undefined; const lineHeightDefault = lineHeights[1].lineHeight; const textAlignDefault = [textAlignItems[0].alignment]; const fontSizeDefault = fontSizes[2].size; const headingDefault = headings[0].text; function onButtonClick(name: string) { notify(`The "${name}" button has been clicked`); } function onSelectionChanged(name: string) { notify(`The "${name}" value has been changed`); } function App() { const [lineHeight, setLineHeight] = useState(lineHeightDefault); const [textAlign, setTextAlign] = useState(textAlignDefault); const [fontSize, setFontSize] = useState(fontSizeDefault); const [heading, setHeading] = useState(headingDefault); const [multiline, setMultiline] = useState(true); const onFontFamilyClick = useCallback(() => { notify('The "Font Family" value has been changed'); }, []); const onUndoButtonClick = useCallback(() => { onButtonClick('Undo'); }, []); const onButtonGroupClick = useCallback((e: ButtonGroupTypes.ItemClickEvent) => { onButtonClick(e.itemData.hint); }, []); const onRedoButtonClick = useCallback(() => { onButtonClick('Redo'); }, []); const onLinkButtonClick = useCallback(() => { onButtonClick('Link'); }, []); const onAddImageButtonClick = useCallback(() => { onButtonClick('Add Image'); }, []); const onClearButtonClick = useCallback(() => { onButtonClick('Clear Formating'); }, []); const onCodeBlockButtonClick = useCallback(() => { onButtonClick('Code Block'); }, []); const onQuoteButtonClick = useCallback(() => { onButtonClick('Blockquote'); }, []); const onAttachButtonClick = useCallback(() => { onButtonClick('Attach'); }, []); const onAboutButtonClick = useCallback(() => { onButtonClick('Attach'); }, []); const onHeadingClick = useCallback( (e: SelectBoxTypes.ItemClickEvent) => { setHeading(e.itemData.text); notify('The "Heading" value has been changed'); }, [setHeading], ); const onLineHeightChanged = useCallback( (e: DropDownButtonTypes.SelectionChangedEvent) => { setLineHeight(e.item.lineHeight); onSelectionChanged('Line Height'); }, [setLineHeight], ); const onFontSizeChange = useCallback( (e: DropDownButtonTypes.SelectionChangedEvent) => { setFontSize(e.item.size); onSelectionChanged('Font Size'); }, [setFontSize], ); const onTextAlignChanged = useCallback( (e: ButtonGroupTypes.ItemClickEvent) => { const { alignment, hint } = e.itemData; setTextAlign([alignment]); onButtonClick(hint); }, [setTextAlign], ); const onToolbarLineModeChanged = useCallback( ({ value }) => { setMultiline(value); }, [setMultiline], ); const renderFontSize = useCallback( (itemData) => ( <div style={{ fontSize: `${itemData.size}px` }}>{itemData.text}</div> ), [], ); const renderTextAlign = useCallback( () => ( <ButtonGroup keyExpr="alignment" stylingMode="outlined" items={textAlignItems} selectedItemKeys={textAlign} onItemClick={onTextAlignChanged} ></ButtonGroup> ), [textAlign, onTextAlignChanged], ); const renderTextAlignMenu = useCallback( () => ( <ButtonGroup keyExpr="alignment" stylingMode="outlined" items={textAlignItemsExtended} selectedItemKeys={textAlign} onItemClick={onTextAlignChanged} ></ButtonGroup> ), [textAlign, onTextAlignChanged], ); const renderMenuSeparator = useCallback( () => <div className="toolbar-menu-separator"></div>, [], ); return ( <React.Fragment> <div className="widget-container"> <Resizable className="resizable-container" minWidth={500} minHeight={150} maxHeight={370} handles="right" area=".widget-container" > <Toolbar multiline={multiline}> <Item location="before"> <Button icon="undo" stylingMode={stylingMode} onClick={onUndoButtonClick} ></Button> </Item> <Item location="before"> <Button icon="redo" stylingMode={stylingMode} onClick={onRedoButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before" locateInMenu="auto"> <DropDownButton width="100%" displayExpr="text" keyExpr="size" useSelectMode={true} stylingMode={stylingMode} items={fontSizes} selectedItemKey={fontSize} itemRender={renderFontSize} onSelectionChanged={onFontSizeChange} ></DropDownButton> </Item> <Item location="before" locateInMenu="auto"> <DropDownButton width="100%" icon="indent" displayExpr="text" keyExpr="lineHeight" useSelectMode={true} stylingMode={stylingMode} items={lineHeights} selectedItemKey={lineHeight} onSelectionChanged={onLineHeightChanged} ></DropDownButton> </Item> <Item location="before" locateInMenu="auto"> <SelectBox placeholder="Font" displayExpr="text" inputAttr={fontInputAttr} dataSource={fontFamilies} onItemClick={onFontFamilyClick} ></SelectBox> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before"> <ButtonGroup keyExpr="icon" stylingMode="outlined" selectionMode="multiple" items={fontStyles} onItemClick={onButtonGroupClick} ></ButtonGroup> </Item> <Item location="before"> <div className="toolbar-separator"></div> </Item> <Item widget="dxButtonGroup" location="before" locateInMenu="auto" render={renderTextAlign} menuItemRender={renderTextAlignMenu} ></Item> <Item location="before"> <ButtonGroup keyExpr="alignment" stylingMode="outlined" items={listTypes} onItemClick={onButtonGroupClick} ></ButtonGroup> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before" locateInMenu="auto"> <SelectBox displayExpr="text" valueExpr="text" inputAttr={textStyleInputAttr} dataSource={headings} defaultValue={heading} onItemClick={onHeadingClick} ></SelectBox> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="link" text="Link" stylingMode={stylingMode} onClick={onLinkButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="image" text="Add image" stylingMode={stylingMode} onClick={onAddImageButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="clearformat" text="Clear formating" stylingMode={stylingMode} onClick={onClearButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="codeblock" text="Code block" stylingMode={stylingMode} onClick={onCodeBlockButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="blockquote" text="Blockquote" stylingMode={stylingMode} onClick={onQuoteButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="after" showText="inMenu" widget="dxButton"> <Button icon="attach" text="Attach" stylingMode={stylingMode} onClick={onAttachButtonClick} ></Button> </Item> <Item locateInMenu="always" showText="inMenu" widget="dxButton"> <Button icon="help" text="About" stylingMode={stylingMode} onClick={onAboutButtonClick} ></Button> </Item> </Toolbar> </Resizable> </div> <div className="options-container"> <div className="caption">Options</div> <CheckBox text="Multiline mode" value={multiline} onValueChanged={onToolbarLineModeChanged} /> </div> </React.Fragment> ); } export default App;
import React, { useCallback, useState } from 'react'; import Toolbar, { Item } from 'devextreme-react/toolbar'; import Button from 'devextreme-react/button'; import ButtonGroup from 'devextreme-react/button-group'; import Resizable from 'devextreme-react/resizable'; import CheckBox from 'devextreme-react/check-box'; import DropDownButton from 'devextreme-react/drop-down-button'; import SelectBox from 'devextreme-react/select-box'; import themes from 'devextreme/ui/themes'; import notify from 'devextreme/ui/notify'; import 'devextreme/ui/select_box'; import { fontSizes, lineHeights, fontFamilies, fontStyles, headings, textAlignItems, textAlignItemsExtended, listTypes, fontInputAttr, textStyleInputAttr, } from './data.js'; const stylingMode = !themes.current().startsWith('generic') ? 'text' : undefined; const lineHeightDefault = lineHeights[1].lineHeight; const textAlignDefault = [textAlignItems[0].alignment]; const fontSizeDefault = fontSizes[2].size; const headingDefault = headings[0].text; function onButtonClick(name) { notify(`The "${name}" button has been clicked`); } function onSelectionChanged(name) { notify(`The "${name}" value has been changed`); } function App() { const [lineHeight, setLineHeight] = useState(lineHeightDefault); const [textAlign, setTextAlign] = useState(textAlignDefault); const [fontSize, setFontSize] = useState(fontSizeDefault); const [heading, setHeading] = useState(headingDefault); const [multiline, setMultiline] = useState(true); const onFontFamilyClick = useCallback(() => { notify('The "Font Family" value has been changed'); }, []); const onUndoButtonClick = useCallback(() => { onButtonClick('Undo'); }, []); const onButtonGroupClick = useCallback((e) => { onButtonClick(e.itemData.hint); }, []); const onRedoButtonClick = useCallback(() => { onButtonClick('Redo'); }, []); const onLinkButtonClick = useCallback(() => { onButtonClick('Link'); }, []); const onAddImageButtonClick = useCallback(() => { onButtonClick('Add Image'); }, []); const onClearButtonClick = useCallback(() => { onButtonClick('Clear Formating'); }, []); const onCodeBlockButtonClick = useCallback(() => { onButtonClick('Code Block'); }, []); const onQuoteButtonClick = useCallback(() => { onButtonClick('Blockquote'); }, []); const onAttachButtonClick = useCallback(() => { onButtonClick('Attach'); }, []); const onAboutButtonClick = useCallback(() => { onButtonClick('Attach'); }, []); const onHeadingClick = useCallback( (e) => { setHeading(e.itemData.text); notify('The "Heading" value has been changed'); }, [setHeading], ); const onLineHeightChanged = useCallback( (e) => { setLineHeight(e.item.lineHeight); onSelectionChanged('Line Height'); }, [setLineHeight], ); const onFontSizeChange = useCallback( (e) => { setFontSize(e.item.size); onSelectionChanged('Font Size'); }, [setFontSize], ); const onTextAlignChanged = useCallback( (e) => { const { alignment, hint } = e.itemData; setTextAlign([alignment]); onButtonClick(hint); }, [setTextAlign], ); const onToolbarLineModeChanged = useCallback( ({ value }) => { setMultiline(value); }, [setMultiline], ); const renderFontSize = useCallback( (itemData) => <div style={{ fontSize: `${itemData.size}px` }}>{itemData.text}</div>, [], ); const renderTextAlign = useCallback( () => ( <ButtonGroup keyExpr="alignment" stylingMode="outlined" items={textAlignItems} selectedItemKeys={textAlign} onItemClick={onTextAlignChanged} ></ButtonGroup> ), [textAlign, onTextAlignChanged], ); const renderTextAlignMenu = useCallback( () => ( <ButtonGroup keyExpr="alignment" stylingMode="outlined" items={textAlignItemsExtended} selectedItemKeys={textAlign} onItemClick={onTextAlignChanged} ></ButtonGroup> ), [textAlign, onTextAlignChanged], ); const renderMenuSeparator = useCallback(() => <div className="toolbar-menu-separator"></div>, []); return ( <React.Fragment> <div className="widget-container"> <Resizable className="resizable-container" minWidth={500} minHeight={150} maxHeight={370} handles="right" area=".widget-container" > <Toolbar multiline={multiline}> <Item location="before"> <Button icon="undo" stylingMode={stylingMode} onClick={onUndoButtonClick} ></Button> </Item> <Item location="before"> <Button icon="redo" stylingMode={stylingMode} onClick={onRedoButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before" locateInMenu="auto" > <DropDownButton width="100%" displayExpr="text" keyExpr="size" useSelectMode={true} stylingMode={stylingMode} items={fontSizes} selectedItemKey={fontSize} itemRender={renderFontSize} onSelectionChanged={onFontSizeChange} ></DropDownButton> </Item> <Item location="before" locateInMenu="auto" > <DropDownButton width="100%" icon="indent" displayExpr="text" keyExpr="lineHeight" useSelectMode={true} stylingMode={stylingMode} items={lineHeights} selectedItemKey={lineHeight} onSelectionChanged={onLineHeightChanged} ></DropDownButton> </Item> <Item location="before" locateInMenu="auto" > <SelectBox placeholder="Font" displayExpr="text" inputAttr={fontInputAttr} dataSource={fontFamilies} onItemClick={onFontFamilyClick} ></SelectBox> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before"> <ButtonGroup keyExpr="icon" stylingMode="outlined" selectionMode="multiple" items={fontStyles} onItemClick={onButtonGroupClick} ></ButtonGroup> </Item> <Item location="before"> <div className="toolbar-separator"></div> </Item> <Item widget="dxButtonGroup" location="before" locateInMenu="auto" render={renderTextAlign} menuItemRender={renderTextAlignMenu} ></Item> <Item location="before"> <ButtonGroup keyExpr="alignment" stylingMode="outlined" items={listTypes} onItemClick={onButtonGroupClick} ></ButtonGroup> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before" locateInMenu="auto" > <SelectBox displayExpr="text" valueExpr="text" inputAttr={textStyleInputAttr} dataSource={headings} defaultValue={heading} onItemClick={onHeadingClick} ></SelectBox> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="link" text="Link" stylingMode={stylingMode} onClick={onLinkButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="image" text="Add image" stylingMode={stylingMode} onClick={onAddImageButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="clearformat" text="Clear formating" stylingMode={stylingMode} onClick={onClearButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="codeblock" text="Code block" stylingMode={stylingMode} onClick={onCodeBlockButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" showText="inMenu" widget="dxButton" > <Button icon="blockquote" text="Blockquote" stylingMode={stylingMode} onClick={onQuoteButtonClick} ></Button> </Item> <Item location="before" locateInMenu="auto" menuItemRender={renderMenuSeparator} > <div className="toolbar-separator"></div> </Item> <Item location="after" showText="inMenu" widget="dxButton" > <Button icon="attach" text="Attach" stylingMode={stylingMode} onClick={onAttachButtonClick} ></Button> </Item> <Item locateInMenu="always" showText="inMenu" widget="dxButton" > <Button icon="help" text="About" stylingMode={stylingMode} onClick={onAboutButtonClick} ></Button> </Item> </Toolbar> </Resizable> </div> <div className="options-container"> <div className="caption">Options</div> <CheckBox text="Multiline mode" value={multiline} onValueChanged={onToolbarLineModeChanged} /> </div> </React.Fragment> ); } export default App;
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.tsx'; ReactDOM.render( <App />, document.getElementById('app'), );
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', }, ]; export const fontInputAttr = { 'aria-label': 'Font' }; export const textStyleInputAttr = { 'aria-label': 'Text Style' };
window.exports = window.exports || {}; window.config = { transpiler: 'ts', typescriptOptions: { module: 'system', emitDecoratorMetadata: true, experimentalDecorators: true, jsx: 'react', }, meta: { 'react': { 'esModule': true, }, 'typescript': { 'exports': 'ts', }, 'devextreme/time_zone_utils.js': { 'esModule': true, }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme/viz/palette.js': { 'esModule': true, }, }, paths: { 'npm:': 'https://unpkg.com/', }, defaultExtension: 'js', map: { 'ts': 'npm:plugin-typescript@4.2.4/lib/plugin.js', 'typescript': 'npm:typescript@4.2.4/lib/typescript.js', 'react': 'npm:react@17.0.2/umd/react.development.js', 'react-dom': 'npm:react-dom@17.0.2/umd/react-dom.development.js', 'prop-types': 'npm:prop-types@15.8.1/prop-types.js', 'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.28.1/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@24.1.7/cjs', 'devextreme-react': 'npm:devextreme-react@24.1.7/cjs', 'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@1.7.1/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.2.13/dist/dx-diagram.js', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.56/dist/dx-gantt.js', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.13', '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', 'devextreme-cldr-data': 'npm:devextreme-cldr-data@1.0.3', // SystemJS plugins '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.8/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js', }, packages: { 'devextreme': { defaultExtension: 'js', }, 'devextreme-react': { main: 'index.js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/localization/messages': { format: 'json', defaultExtension: 'json', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.13/inferno/package.json', ], babelOptions: { sourceMaps: false, stage0: true, react: true, }, }; System.config(window.config);
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.js'; ReactDOM.render(<App />, document.getElementById('app'));
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', }, ]; export const fontInputAttr = { 'aria-label': 'Font' }; export const textStyleInputAttr = { 'aria-label': 'Text Style' };
<!DOCTYPE html> <html lang="en"> <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=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/24.1.7/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="styles.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.tsx"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"></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; }

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.