Skip to main content

Styling

In chart-react we are using the styled-components library under the hood, so because of this, chart-react has some options to override default components styles. Let's break it down!

Styled-Components Cascades

In a styled-components there is a thing like referring to other components inside interpolation function. So you can use it without a limit to apply custom styles for every styled component, no matter how deep in the structure it is located.

Consider we've created a wrapper ChartReactApp component around our chart-react app, which only wires all necessary dependencies. To style everything underneath it, we should wrap our ChartReactApp inside a styled, and write styles here.

export const InitChartReactAppStyled = () => {
const ChartReactAppStyled = styled(ChartReactApp)``;
// TODO fix TS error
// @ts-ignore
return <ChartReactAppStyled />;
}

Let's change styles for the Studies Settings popup component, for it we should do the following:

import {
PopupContainerStyled,
PopupFooterStyled,
PopupHeaderStyled,
} from '@dx-private/dxchart5-react/dist/chart-kit/Popup/PopupUI.styled';
import { ChartReactApp } from '@dx-private/dxchart5-react/dist/chart/chart-react-app';
import {
FooterButtonStyled,
StudiesSettingsPopupStyled,
} from '@dx-private/dxchart5-react/dist/chart/components/studies/studies-settings/studies-settings-popup.styled';
import styled from 'styled-components';
/**
* StudiesSettingsPopupStyled and etc are components itself
* which you should import to use as a class selector
*/
// Under the hood styled-components simply interpolates these components to the associated classnames
export const ChartReactAppStyled = styled(ChartReactApp)`
${StudiesSettingsPopupStyled} {
${PopupHeaderStyled} {
background-color: #717744;
color: #eff1ed;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
${PopupContainerStyled} {
background-color: #bcbd8b;
border: 2px solid #766153;
border-radius: 0;
}
${PopupFooterStyled} {
background-color: #717744;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
justify-content: flex-start;
padding: 10px 10px;
}
${FooterButtonStyled} {
background-color: #766153;
color: #eff1ed;
:hover {
background-color: #373d20;
}
}
}
`;

Someday your styles will end up with a lot lines of code. But we can split it to different files:

// studies-settings-popup.styled.ts
import {
PopupContainerStyled,
PopupFooterStyled,
PopupHeaderStyled,
} from '@dx-private/dxchart5-react/dist/chart-kit/Popup/PopupUI.styled';
import {
FooterButtonStyled,
StudiesSettingsPopupStyled,
} from '@dx-private/dxchart5-react/dist/chart/components/studies/studies-settings/studies-settings-popup.styled';
import { css } from 'styled-components';
export const StudiesSettingsStyled = css`
${StudiesSettingsPopupStyled} {
${PopupHeaderStyled} {
background-color: #717744;
color: #eff1ed;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
${PopupContainerStyled} {
background-color: #bcbd8b;
border: 2px solid #766153;
border-radius: 0;
}
${PopupFooterStyled} {
background-color: #717744;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
justify-content: flex-start;
padding: 10px 10px;
}
${FooterButtonStyled} {
background-color: #766153;
color: #eff1ed;
:hover {
background-color: #373d20;
}
}
}
`;

import { ChartReactApp } from '@dx-private/dxchart5-react/dist/chart/chart-react-app';
import styled from 'styled-components';
import { StudiesSettingsStyled } from './studies-settings-popup.styled';
// ${() => StudiesSettingsStyled} is a way to interpolate the styles from the css`` function;
export const ChartReactAppStyled = styled(ChartReactApp)`
${() => StudiesSettingsStyled}
`;

Overriding Styles For a General UI-Components

To overwrite the general UI components styles in the whole app we can do something like:

// checkbox.styled.ts
import {
CheckboxIconStyled,
CheckboxInputStyled,
CheckboxViewStyled,
} from '@dx-private/dxchart5-react/dist/chart-kit/Checkbox/Checkbox.styled';
import { css } from 'styled-components';
export const StyledCheckbox = css`
${CheckboxIconStyled} {
fill: #eff1ed;
}
${CheckboxViewStyled} {
border-color: #eff1ed;
}
${CheckboxInputStyled}:hover + ${CheckboxViewStyled} {
border-color: #766153;
}
${CheckboxInputStyled}:active + ${CheckboxViewStyled} {
border-color: #766153;
}
`;

// selectbox.styled.ts
import {
SelectboxAnchorCaretStyled,
SelectboxAnchorContentStyled,
SelectboxAnchorStyled,
} from '@dx-private/dxchart5-react/dist/chart-kit/Selectbox/SelectboxAnchor.styled';
import { css } from 'styled-components';
export const StyledSelectbox = css`
${SelectboxAnchorStyled} {
background-color: #717744;
border-radius: 0;
:hover {
background-color: #766153;
}
}
${SelectboxAnchorCaretStyled} {
color: #eff1ed;
}
${SelectboxAnchorContentStyled} {
color: #eff1ed;
}
`;

And then use it like before, in the root of ChartReactAppStyled:

export const ChartReactAppStyled = () => {
const ChartReactAppStyled = styled(ChartReactApp)`
/*
ui-components styles overridings
*/
${() => StyledCheckbox}
${() => StyledSelectbox}
`;
return ChartReactAppStyled;
}

Styling Popover and Popup Components

Popover and Popup components from the chart-kit have some limitations in styling. Because they are appended to the <div id="chart-react-wrapper" /> in the DOM, they can only be styled from the element that is upper in the DOM tree then that div, like we have done previously with the <ChartReactAppStyled /> example.

Example

Source code:

import React from 'react';
import styled, { css } from 'styled-components';
import { ChartReactAppWrapper } from '../../../src/components/ChartReactApp';
import {
StudiesSettingsPopupStyled,
FooterButtonStyled,
} from '@dx-private/dxchart5-react/dist/chart/components/studies/studies-settings/studies-settings-popup.styled';
import {
PopupFooterStyled,
PopupContainerStyled,
PopupHeaderStyled,
} from '@dx-private/dxchart5-react/dist/chart-kit/Popup/PopupUI.styled';
import {
IndicatorContainerStyled,
IndicatorTitleStyled,
} from '@dx-private/dxchart5-react/dist/chart/components/studies/studies-settings/components/indicator-list/indicator-list-section.styled';
import { IndicatorListItemContainerStyled } from '@dx-private/dxchart5-react/dist/chart/components/studies/studies-settings/components/indicator-list/indicator-list-item.styled';
import {
LeftSectionStyled,
RightSectionStyled,
DeleteButtonStyled,
} from '@dx-private/dxchart5-react/dist/chart/components/studies/studies-settings/components/studies-settings-content/studies-settings-content.styled';
import {
StudySettingsTitleStyled,
RestoreToDefaultButtonStyled,
InputsBlockTitleStyled,
LabeledFormFieldLabelStyled,
SelectBoxItemStyled,
} from '@dx-private/dxchart5-react/dist/chart/components/studies/studies-settings/components/study-settings/study-settings.styled';
import { CheckboxContainerStyled } from '@dx-private/dxchart5-react/dist/chart-kit/Checkbox/Checkbox.styled';
import {
CheckboxIconStyled,
CheckboxViewStyled,
CheckboxInputStyled,
} from '@dx-private/dxchart5-react/dist/chart-kit/Checkbox/Checkbox.styled';
import {
SelectboxAnchorStyled,
SelectboxAnchorCaretStyled,
SelectboxAnchorContentStyled,
} from '@dx-private/dxchart5-react/dist/chart-kit/Selectbox/SelectboxAnchor.styled';
import { PopoverStyled, PopoverContentStyled } from '@dx-private/dxchart5-react/dist/chart-kit/Popover/Popover.styled';
import { DropdownMenuItemStyled } from '@dx-private/dxchart5-react/dist/chart-kit/Menu/dropdown-menu/DropdownMenuItem.styled';
import { MenuStyled } from '@dx-private/dxchart5-react/dist/chart-kit/Menu/Menu.styled';
import { CompareChartNoDataContentStyled } from '@dx-private/dxchart5-react/dist/chart/components/compare-chart/compare-chart-selector.styled';
import {
MultichartSettingsLayoutSelectorItemStyled,
MultichartSettingsHeaderStyled,
MultichartSettingsOptionTextStyled,
} from '@dx-private/dxchart5-react/dist/chart/components/multichart-settings/multichart-settings.styled';
import {
DrawingSelectorFooterButtonStyled,
DrawingSelectorFooterStyled,
} from '@dx-private/dxchart5-react/dist/chart/components/drawings/drawings-selector/drawings-selector-footer.styled';
export const StyledChartReactApp = () => {
// TODO fix TS error
// @ts-ignore
return <ChartReactAppWrapperStyled width="80%" height="500px" />;
};
const ChartReactAppWrapperStyled = styled(ChartReactAppWrapper)`
/*
Popups overridings
*/
${() => StyledStudiesSettingsPopup}
/*
ui-components styles overridings
*/
${() => StyledCheckbox}
${() => StyledSelectbox}
${() => StyledPopover}
/*
Popovers
Concrete popovers overridings
*/
${() => StyledStudySettingsPopover}
${() => StyledDrawingsSelectorPopover}
${() => StyledCompareChartPopover}
${() => StyledMultichartPopover}
`;
const StyledStudiesSettingsPopup = css`
${StudiesSettingsPopupStyled} {
${() => StyledStudiesSettingsLeftSection}
${() => StyledStudiesSettingsRightSection}
${PopupHeaderStyled} {
background-color: #717744;
color: #eff1ed;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
${PopupContainerStyled} {
background-color: #bcbd8b;
border: 2px solid #766153;
border-radius: 0;
}
${PopupFooterStyled} {
background-color: #717744;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
justify-content: flex-start;
padding: 10px 10px;
}
${FooterButtonStyled} {
background-color: #766153;
color: #eff1ed;
:hover {
background-color: #373d20;
}
}
}
`;
const StyledStudiesSettingsLeftSection = css`
${LeftSectionStyled} {
${IndicatorContainerStyled} {
border-right: 1px solid #766153;
}
${IndicatorListItemContainerStyled} {
color: #eff1ed;
:hover {
background-color: #766153;
}
}
${IndicatorTitleStyled} {
color: #373d20;
}
}
`;
const StyledStudiesSettingsRightSection = css`
${RightSectionStyled} {
${() => StyledStudySettings};
${IndicatorTitleStyled} {
color: #373d20;
}
${DeleteButtonStyled} {
color: #766153;
:hover {
color: #373d20;
}
}
}
`;
const StyledStudySettings = css`
${() => StyledStudySettingsInputsBlock};
${StudySettingsTitleStyled} {
color: #373d20;
}
${RestoreToDefaultButtonStyled} {
color: #766153;
:hover {
color: #373d20;
}
}
`;
const StyledStudySettingsInputsBlock = css`
${InputsBlockTitleStyled} {
color: #766153;
}
${LabeledFormFieldLabelStyled} {
color: #eff1ed;
}
`;
const StyledCheckbox = css`
${CheckboxContainerStyled} {
${CheckboxIconStyled} {
fill: #eff1ed;
}
${CheckboxViewStyled} {
border-color: #eff1ed;
}
${CheckboxInputStyled}:hover + ${CheckboxViewStyled} {
border-color: #766153;
}
${CheckboxInputStyled}:active + ${CheckboxViewStyled} {
border-color: #766153;
}
}
`;
const StyledSelectbox = css`
${SelectboxAnchorStyled} {
background-color: #717744;
border-radius: 0;
:hover {
background-color: #766153;
}
}
${SelectboxAnchorCaretStyled} {
color: #eff1ed;
}
${SelectboxAnchorContentStyled} {
color: #eff1ed;
}
`;
const StyledPopover = css`
${PopoverStyled} {
border-radius: 0;
background-color: #717744;
border: 2px solid #766153;
${PopoverContentStyled}:not(:empty) {
background-color: #717744;
}
${MenuStyled} {
padding: 0;
}
${DropdownMenuItemStyled} {
background-color: #717744;
margin: 0;
:hover {
border-radius: 0;
background-color: #766153;
}
}
}
`;
const StyledStudySettingsPopover = css`
${PopoverStyled} {
${SelectBoxItemStyled} {
:hover {
border-radius: 0;
background-color: #bcbd8b;
}
}
}
`;
const StyledDrawingsSelectorPopover = css`
${PopoverStyled} {
${DrawingSelectorFooterStyled} {
&::after {
background-color: #eff1ed;
}
}
${DrawingSelectorFooterButtonStyled} {
color: #eff1ed;
:hover {
border-radius: 0;
background-color: #766153;
}
&:disabled,
&[disabled] {
cursor: not-allowed;
}
}
}
`;
const StyledCompareChartPopover = css`
${CompareChartNoDataContentStyled} {
color: #eff1ed;
}
`;
const StyledMultichartPopover = css`
${MultichartSettingsLayoutSelectorItemStyled} {
background-color: #bcbd8b;
}
${MultichartSettingsHeaderStyled} {
color: #eff1ed;
}
${MultichartSettingsOptionTextStyled} {
color: #eff1ed;
}
`;