Overriding the Sidebar component
To override the default Sidebar component, input DrawingsSidebarComponent or DrawingsSidebarFooter to the uiOverrides.DrawingsSidebar property on ChartReactApp (or on createWidget in the vanilla widget).
To remove specific drawing tools or change their order without a full sidebar rewrite, use drawingsList in chart config — see Drawings configuration. Deeper custom hierarchy beyond drawingsList groups requires a full sidebar uiOverrides implementation.
The Sidebar component has the following properties:
interface DrawingSidebarProps {readonly drawingGroups: DrawingGroup[];readonly onSidebarToggle: (isExpanded: boolean) => void;readonly onButtonClick: (type: SidebarFooterButtonType) => void;readonly onDrawingClick: (type: DrawingType) => void;readonly buttonsState: ButtonsState;readonly isSidebarExpanded: boolean;readonly drawingsDisabled: boolean;readonly onFavorite: (name: DrawingType) => void;readonly onUnFavorite: (name: DrawingType) => void;readonly favoriteDrawings: Array<DrawingType>;readonly activeDrawingType: DrawingType | string;readonly icons: IconsPool;readonly startNewIconDrawing: (iconType: IconsPoolNames) => void;}
The Sidebar Footer component has the following properties:
interface DrawingsSidebarFooterProps {readonly buttonsState: ButtonsState;readonly expanded: boolean;readonly disabled?: boolean;readonly onButtonClick: (type: SidebarFooterButtonType) => void;}
Example
The below example shows how to make a customized Sidebar with custom scrollable list of drawings and the Sidebar Footer with Hide and Sync buttons removed.
Source code
import { ChartReactAppContainer, ChartReactAppWrapper } from '../../../../../src/components/ChartReactApp';import { FlexContainer } from '../../../../../src/components/FlexContainer';import React, { memo, useCallback, useContext, useRef } from 'react';import { DrawingSidebarProps } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-drawings-sidebar.component';import { OverrideProps, useIcons } from '@dx-private/dxchart5-react/dist/chart/ui-overrides';import { CREATE_MOCK_PROVIDERS } from '@dx-private/dxchart5-react-mock-providers';import { ChartReactAPI } from '@dx-private/dxchart5-react/dist/chart/view-models/api/chart-react-api.view-model';import {DrawingsSidebarFooter as DefaultDrawingsSidebarFooter,DrawingsSidebarFooterProps,} from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-drawings-sidebar-footer.component';import { DrawingsSidebarHeader } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-drawings-sidebar-header.component';import { DrawingType, isDrawingType } from '@dx-private/dxchart5-react/dist/chart/model/drawing.model';import { DrawingsSidebarDrawingIcon } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/components/chart-drawings-sidebar-drawing-icon.component';import { DrawingsSidebarDrawing } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/components/chart-drawings-sidebar-drawing.component';import { SidebarSeparatorStyled } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/components/chart-drawings-sidebar-separator.styled';import { MultiChartComponentContext } from '@dx-private/dxchart5-react/dist/chart/components/multi-chart/multi-chart-context';import {SidebarFooterButtonType,SidebarFooterButtonTypes,} from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-sidebar.model';import { useA11yListboxArrowsFocusController } from '@dx-private/dxchart5-react/dist/chart-kit/accessibility/use-a11y-listbox-arrows-focus-controller';import { DrawingsSidebarButtonWithTooltip } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/components/chart-drawings-sidebar-button-with-tooltip.component';import {getSidebarFooterButtonName,getSidebarFooterIconByType,} from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/footer-functions';import { DrawingsSidebarFooterStyled } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-drawings-sidebar-footer.styled';export const DrawingsSidebarComponent = ({chartReactAPIProps: _chartApi,originalProps: props,}: OverrideProps<DrawingSidebarProps>) => {const isActiveDrawing = useCallback((type: string | number) => (!isDrawingType(props.activeDrawingType) ? false : props.activeDrawingType === type),[props.activeDrawingType],);return (<divstyle={{display: 'flex',flexFlow: 'column',justifyContent: 'space-between',backgroundColor: 'black',alignItems: 'center',}}><DrawingsSidebarHeaderdisabled={props.drawingsDisabled}expanded={props.isSidebarExpanded}onToggleExpanded={props.onSidebarToggle}/><div style={{ overflowY: 'scroll', scrollbarWidth: 'none' }}>{props.drawingGroups.map((group, i) => {return (<React.Fragment key={group.groupName}>{group.drawings.map((type: DrawingType) => {const favorite = props.favoriteDrawings.includes(type);return type === 'icon' ? (<DrawingsSidebarDrawingIcondisabled={props.drawingsDisabled}key={type}icons={props.icons}active={isActiveDrawing(type)}expanded={props.isSidebarExpanded}onSelectIcon={() => void 0}/>) : (<DrawingsSidebarDrawingkey={type}type={type}disabled={props.drawingsDisabled}active={isActiveDrawing(type)}expanded={props.isSidebarExpanded}favorite={favorite}onSelect={() => void 0}onAddToFavorites={() => void 0}onRemoveFromFavorites={() => void 0}/>);})}{i === props.drawingGroups.length - 1 ? null : (<SidebarSeparatorStyledrole="separator"styles={{ height: 1 }}key={group.groupName}scrollTop={1}/>)}</React.Fragment>);})}</div><DefaultDrawingsSidebarFooterdisabled={props.drawingsDisabled}expanded={props.isSidebarExpanded}buttonsState={props.buttonsState}onButtonClick={props.onButtonClick}/></div>);};/* remove HIDE and SYNC buttons from sidebar footer */const sidebarFooterButtonTypes = ['MAGNET','DRAWING_MODE',// 'SYNC_DRAWINGS',// 'HIDE_DRAWINGS','DELETE_DRAWINGS',] as const;const DrawingsSidebarFooter = memo((overrideProps: OverrideProps<DrawingsSidebarFooterProps>) => {const { chartReactAPIProps: _chartApi, originalProps: props } = overrideProps;const { expanded, disabled = false, onButtonClick, buttonsState } = props;const iconsConfig = useIcons();const { localization } = useContext(MultiChartComponentContext);const footerListRef = useRef<HTMLDivElement>(null);const isActive = useCallback((type: SidebarFooterButtonType) => {switch (type) {case SidebarFooterButtonTypes.DRAWING_MODE:return buttonsState.drawingModeOn;case SidebarFooterButtonTypes.MAGNET:return buttonsState.magnetOn;case SidebarFooterButtonTypes.HIDE_DRAWINGS:return !buttonsState.drawingsVisible;case SidebarFooterButtonTypes.DELETE_DRAWINGS:return false;case SidebarFooterButtonTypes.SYNC_DRAWINGS:return buttonsState.drawingSyncEnabled;}},[buttonsState],);useA11yListboxArrowsFocusController({wrapperRef: footerListRef,childrenSelector: 'li',direction: 'vertical',role: 'listbox',});const renderSidebarFooterToolbarItem = (type: SidebarFooterButtonType, supressSelect: boolean = false) => {return (<DrawingsSidebarButtonWithTooltipkey={type}icon={getSidebarFooterIconByType(type, iconsConfig, buttonsState)}label={getSidebarFooterButtonName(type, localization.sidebar, buttonsState)}expanded={expanded}onClick={() => !supressSelect && onButtonClick(type)}disableTooltip={expanded}disabled={disabled}isActive={isActive(type)}/>);};return (<><SidebarSeparatorStyled role="separator" styles={{ height: 1 }} scrollTop={1} /><DrawingsSidebarFooterStyledaria-orientation="vertical"aria-label={localization.sidebar.a11y_footerList}ref={footerListRef}expanded={expanded}>{sidebarFooterButtonTypes.map(type => renderSidebarFooterToolbarItem(type))}</DrawingsSidebarFooterStyled></>);});export const OverridingSidebarComponent = () => {const onApiCreated = (api: ChartReactAPI) => {api.onChartCreated((_chartId, _chartInstance) => {});};const chartReactAppContainerProps = { width: 800, height: 50 };return (<><ChartReactAppContainer {...chartReactAppContainerProps}><div className={'chart-react-container'} /></ChartReactAppContainer><FlexContainer $justifyContent={'flex-start'}><ChartReactAppWrapperdependencies={{ ...CREATE_MOCK_PROVIDERS(), onApiCreated }}uiOverrides={{DrawingsSidebar: {/* you can change both components at the same time, but you will have to add default footer component inside sidebar */DrawingsSidebarComponent,DrawingsSidebarFooter,},}}/></FlexContainer></>);};