Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(theme): base theme prop #333

Merged
merged 4 commits into from
Aug 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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