Skip to content

Commit

Permalink
feat(theme): base theme prop (#333)
Browse files Browse the repository at this point in the history
* Allow `baseTheme` prop to set base theme, default is still `LIGHT_THEME`
* refactor: theme type logic

BREAKING CHANGE: remove `baseThemeType` prop on `Settings` component and `BaseThemeTypes` type.

#292
  • Loading branch information
nickofthyme authored Aug 21, 2019
1 parent abaa472 commit a9ff5e1
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 36 deletions.
2 changes: 2 additions & 0 deletions src/chart_types/xy_chart/store/chart_state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ChartStore } from './chart_state';

describe('Chart Store', () => {
let store = new ChartStore();
store.chartTheme = LIGHT_THEME;

const SPEC_ID = getSpecId('spec_1');
const AXIS_ID = getAxisId('axis_1');
Expand Down Expand Up @@ -67,6 +68,7 @@ describe('Chart Store', () => {
};
beforeEach(() => {
store = new ChartStore();
store.chartTheme = LIGHT_THEME;
store.updateParentDimensions(600, 600, 0, 0);
store.computeChart();
});
Expand Down
6 changes: 4 additions & 2 deletions src/chart_types/xy_chart/store/chart_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import {
Rotation,
} from '../utils/specs';
import { formatTooltip, getSeriesTooltipValues } from '../tooltip/tooltip';
import { LIGHT_THEME } from '../../../utils/themes/light_theme';
import { mergeWithDefaultAnnotationLine, mergeWithDefaultAnnotationRect, Theme } from '../../../utils/themes/theme';
import { compareByValueAsc } from '../../../utils/commons';
import { computeChartDimensions } from '../utils/dimensions';
Expand Down Expand Up @@ -150,7 +149,10 @@ export class ChartStore {

chartRotation: Rotation = 0; // updated from jsx
chartRendering: Rendering = 'canvas'; // updated from jsx
chartTheme: Theme = LIGHT_THEME; // updated from jsx
/**
* Chart theme to be set from Settings.tsx
*/
chartTheme!: Theme;
axesSpecs: Map<AxisId, AxisSpec> = new Map(); // readed from jsx
axesTicksDimensions: Map<AxisId, AxisTicksDimensions> = new Map(); // computed
axesPositions: Map<AxisId, Dimensions> = new Map(); // computed
Expand Down
9 changes: 4 additions & 5 deletions src/specs/settings.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import { mount } from 'enzyme';
import * as React from 'react';
import { Position, Rendering, Rotation } from '../chart_types/xy_chart/utils/specs';
import { DARK_THEME } from '../utils/themes/dark_theme';
import { LIGHT_THEME } from '../utils/themes/light_theme';
import { TooltipType } from '../chart_types/xy_chart/utils/interactions';
import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
import { DEFAULT_TOOLTIP_SNAP, DEFAULT_TOOLTIP_TYPE, SettingsComponent, SettingSpecProps } from './settings';
import { PartialTheme, BaseThemeTypes } from '../utils/themes/theme';
import { PartialTheme } from '../utils/themes/theme';

describe('Settings spec component', () => {
test('should update store on mount if spec has a chart store', () => {
Expand Down Expand Up @@ -56,7 +55,7 @@ describe('Settings spec component', () => {
test('should set chart properties on chart store', () => {
const chartStore = new ChartStore();

expect(chartStore.chartTheme).toEqual(LIGHT_THEME);
expect(chartStore.chartTheme).toBeUndefined();
expect(chartStore.chartRotation).toBe(0);
expect(chartStore.chartRendering).toBe('canvas');
expect(chartStore.animateData).toBe(false);
Expand Down Expand Up @@ -163,11 +162,11 @@ describe('Settings spec component', () => {
},
};

expect(chartStore.chartTheme).toEqual(LIGHT_THEME);
expect(chartStore.chartTheme).toBeUndefined();

const updatedProps: SettingSpecProps = {
theme: partialTheme,
baseThemeType: BaseThemeTypes.Dark,
baseTheme: DARK_THEME,
rotation: 90 as Rotation,
rendering: 'svg' as Rendering,
animateData: true,
Expand Down
31 changes: 17 additions & 14 deletions src/specs/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { PureComponent } from 'react';
import { inject } from 'mobx-react';

import { DomainRange, Position, Rendering, Rotation } from '../chart_types/xy_chart/utils/specs';
import { LIGHT_THEME } from '../utils/themes/light_theme';
import { DARK_THEME } from '../utils/themes/dark_theme';
import { BaseThemeType, mergeWithDefaultTheme, PartialTheme, Theme, BaseThemeTypes } from '../utils/themes/theme';
import { mergeWithDefaultTheme, PartialTheme, Theme } from '../utils/themes/theme';
import { Domain } from '../utils/domain';
import { TooltipType, TooltipValueFormatter } from '../chart_types/xy_chart/utils/interactions';
import {
Expand All @@ -16,6 +14,7 @@ import {
CursorUpdateListener,
} from '../chart_types/xy_chart/store/chart_state';
import { ScaleTypes } from '../utils/scales/scales';
import { LIGHT_THEME } from '../utils/themes/light_theme';

export const DEFAULT_TOOLTIP_TYPE = TooltipType.VerticalCursor;
export const DEFAULT_TOOLTIP_SNAP = true;
Expand Down Expand Up @@ -52,8 +51,16 @@ function isTooltipType(config: TooltipType | TooltipProps): config is TooltipTyp

export interface SettingSpecProps {
chartStore?: ChartStore;
/**
* Full or partial theme to be merged with base
*/
theme?: Theme | PartialTheme;
baseThemeType?: BaseThemeType;
/**
* Full default theme to use as base
*
* @default `LIGHT_THEME`
*/
baseTheme?: Theme;
rendering: Rendering;
rotation: Rotation;
animateData: boolean;
Expand All @@ -76,20 +83,16 @@ export interface SettingSpecProps {
xDomain?: Domain | DomainRange;
}

function getTheme(theme?: Theme | PartialTheme, baseThemeType: BaseThemeType = BaseThemeTypes.Light): Theme {
if (theme) {
const baseTheme = baseThemeType === BaseThemeTypes.Light ? LIGHT_THEME : DARK_THEME;
return mergeWithDefaultTheme(theme, baseTheme);
}

return LIGHT_THEME;
function getTheme(baseTheme?: Theme, theme?: Theme | PartialTheme): Theme {
const base = baseTheme ? baseTheme : LIGHT_THEME;
return theme ? mergeWithDefaultTheme(theme, base) : base;
}

function updateChartStore(props: SettingSpecProps) {
const {
chartStore,
theme,
baseThemeType,
baseTheme,
rotation,
rendering,
animateData,
Expand All @@ -110,11 +113,12 @@ function updateChartStore(props: SettingSpecProps) {
debug,
xDomain,
} = props;

if (!chartStore) {
return;
}

chartStore.chartTheme = getTheme(theme, baseThemeType);
chartStore.chartTheme = getTheme(baseTheme, theme);
chartStore.chartRotation = rotation;
chartStore.chartRendering = rendering;
chartStore.animateData = animateData;
Expand Down Expand Up @@ -176,7 +180,6 @@ export class SettingsComponent extends PureComponent<SettingSpecProps> {
animateData: true,
showLegend: false,
debug: false,
baseThemeType: BaseThemeTypes.Light,
tooltip: {
type: DEFAULT_TOOLTIP_TYPE,
snap: DEFAULT_TOOLTIP_SNAP,
Expand Down
7 changes: 0 additions & 7 deletions src/utils/themes/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,6 @@ export interface Theme {

export type PartialTheme = RecursivePartial<Theme>;

export const BaseThemeTypes = Object.freeze({
Light: 'light' as 'light',
Dark: 'dark' as 'dark',
});

export type BaseThemeType = typeof BaseThemeTypes.Dark | typeof BaseThemeTypes.Light;

export type DisplayValueStyle = TextStyle & {
offsetX: number;
offsetY: number;
Expand Down
52 changes: 44 additions & 8 deletions stories/styling.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ import {
Position,
ScaleType,
Settings,
BaseThemeTypes,
LineSeriesStyle,
TooltipType,
RecursivePartial,
Theme,
LIGHT_THEME,
DARK_THEME,
} from '../src/';
import * as TestDatasets from '../src/utils/data_samples/test_dataset';
import { palettes } from '../src/utils/themes/colors';
Expand Down Expand Up @@ -392,7 +393,7 @@ storiesOf('Stylings', module)
<Chart className={className}>
<Settings
theme={theme}
baseThemeType={darkmode ? 'dark' : 'light'}
baseTheme={darkmode ? DARK_THEME : LIGHT_THEME}
debug={boolean('debug', false)}
showLegend={true}
legendPosition={Position.Right}
Expand Down Expand Up @@ -442,7 +443,7 @@ storiesOf('Stylings', module)
</Chart>
);
})
.add('partial custom theme', () => {
.add('partial custom theme with baseThemeType', () => {
const customPartialTheme: PartialTheme = {
barSeriesStyle: {
rectBorder: {
Expand All @@ -454,12 +455,47 @@ storiesOf('Stylings', module)

return (
<Chart className="story-chart">
<Settings
showLegend
theme={customPartialTheme}
baseThemeType={BaseThemeTypes.Light}
legendPosition={Position.Right}
<Settings showLegend theme={customPartialTheme} baseTheme={LIGHT_THEME} legendPosition={Position.Right} />
<Axis id={getAxisId('bottom')} position={Position.Bottom} title="Bottom axis" showOverlappingTicks={true} />
<Axis
id={getAxisId('left2')}
title="Left axis"
position={Position.Left}
tickFormat={(d) => Number(d).toFixed(2)}
/>
<Axis id={getAxisId('top')} position={Position.Top} title="Top axis" showOverlappingTicks={true} />
<Axis
id={getAxisId('right')}
title="Right axis"
position={Position.Right}
tickFormat={(d) => Number(d).toFixed(2)}
/>
<BarSeries
id={getSpecId('bars')}
xScaleType={ScaleType.Linear}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['y']}
splitSeriesAccessors={['g']}
stackAccessors={['x']}
data={data1}
/>
</Chart>
);
})
.add('partial custom theme with baseTheme', () => {
const customPartialTheme: PartialTheme = {
barSeriesStyle: {
rectBorder: {
stroke: color('BarBorderStroke', 'white'),
visible: true,
},
},
};

return (
<Chart className="story-chart">
<Settings showLegend theme={customPartialTheme} baseTheme={LIGHT_THEME} legendPosition={Position.Right} />
<Axis id={getAxisId('bottom')} position={Position.Bottom} title="Bottom axis" showOverlappingTicks={true} />
<Axis
id={getAxisId('left2')}
Expand Down

0 comments on commit a9ff5e1

Please sign in to comment.