Skip to content

Commit

Permalink
feat: add dark theme (#44)
Browse files Browse the repository at this point in the history
* feat(theme): add dark theme

The Dark Theme is now available.
The AxisConfig has now a cleaner styling, splitted by axis or tick styles.
Changing a theme is now easier and it's not necessary tied to a darkmode flag. New
theme can be added and used on the charts.

fix #35

BREAKING CHANGE: The `Theme.AxisConfig` type has a different signature.
It now contains `axisTitleStyle`, `axisLineStyle`, `tickLabelStyle` and
`tickLineStyle` defined as `TextStyle` or `StrokeStyle` elements.
The `Theme` interface is changed in a more flat structure.
`darkMode` prop from `Setting` is removed.
`theme` prop in `Setting` is now a `Theme` type object, not a `PartialTheme`.
You can use `mergeWithDefaultTheme` function to merge an existing theme
with a partial one.
  • Loading branch information
markov00 authored Feb 19, 2019
1 parent 80112a7 commit 766f1ad
Show file tree
Hide file tree
Showing 32 changed files with 922 additions and 473 deletions.
12 changes: 10 additions & 2 deletions .storybook/config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import '@elastic/eui/dist/eui_theme_light.css';
import { withInfo } from '@storybook/addon-info';
import { withKnobs } from '@storybook/addon-knobs';
import { withOptions } from '@storybook/addon-options';
import { addDecorator, configure } from '@storybook/react';
import '../src/index.scss';
import './style.css';
import './style.scss';
import { switchTheme } from './theme_service';

switchTheme('light');

addDecorator(
withOptions({
Expand All @@ -19,6 +21,12 @@ addDecorator(
withInfo({
inline: true,
source: false,
styles: {
infoBody: {
marginTop: 0,
marginBottom: 0,
},
},
}),
);

Expand Down
8 changes: 8 additions & 0 deletions .storybook/style.css → .storybook/style.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
@import '../node_modules/@elastic/eui/src/themes/eui/eui_colors_dark.scss';

.story-chart {
background: white;
}
.story-chart-dark {
background: $euiColorEmptyShade;
}
#root {
background-color: blanchedalmond;
}
Expand All @@ -21,3 +26,6 @@
border: 1px solid gray;
padding: 5px;
}
.Pane.vertical.Pane1 {
background: red;
}
17 changes: 17 additions & 0 deletions .storybook/theme_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @ts-ignore
import themeDark from '!!style-loader/useable!css-loader!@elastic/eui/dist/eui_theme_dark.css';
// @ts-ignore
import themeLight from '!!style-loader/useable!css-loader!@elastic/eui/dist/eui_theme_light.css';

export function switchTheme(theme: string) {
switch (theme) {
case 'light':
themeDark.unuse();
themeLight.use();
return;
case 'dark':
themeLight.unuse();
themeDark.use();
return;
}
}
4 changes: 2 additions & 2 deletions src/components/_legend.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
$elasticChartsLegendMaxWidth: $euiSize * 10 + $euiSize;
$elasticChartsLegendMaxHeight: $euiSize * 4 + $euiSize;
$elasticChartsLegendMaxWidth: $euiSize * 10;
$elasticChartsLegendMaxHeight: $euiSize * 4;

.elasticChartsLegend {
position: absolute;
Expand Down
8 changes: 4 additions & 4 deletions src/components/legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ class LegendComponent extends React.Component<ReactiveChartProps> {
let paddingStyle;
if (isVertical(legendPosition)) {
paddingStyle = {
paddingTop: chartTheme.chart.margins.top,
paddingBottom: chartTheme.chart.margins.bottom,
paddingTop: chartTheme.chartMargins.top,
paddingBottom: chartTheme.chartMargins.bottom,
};
} else {
paddingStyle = {
paddingLeft: chartTheme.chart.margins.left,
paddingRight: chartTheme.chart.margins.right,
paddingLeft: chartTheme.chartMargins.left,
paddingRight: chartTheme.chartMargins.right,
};
}
return (
Expand Down
60 changes: 30 additions & 30 deletions src/components/react_canvas/area_geometries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ import React from 'react';
import { Circle, Group, Path } from 'react-konva';
import { animated, Spring } from 'react-spring/konva';
import { LegendItem } from '../../lib/series/legend';
import { AreaGeometry, GeometryValue, getGeometryStyle, PointGeometry } from '../../lib/series/rendering';
import { AreaSeriesStyle } from '../../lib/themes/theme';
import {
AreaGeometry,
GeometryValue,
getGeometryStyle,
PointGeometry,
} from '../../lib/series/rendering';
import { AreaSeriesStyle, SharedGeometryStyle } from '../../lib/themes/theme';
import { ElementClickListener, TooltipData } from '../../state/chart_state';

interface AreaGeometriesDataProps {
animated?: boolean;
areas: AreaGeometry[];
num?: number;
style: AreaSeriesStyle;
sharedStyle: SharedGeometryStyle;
onElementClick?: ElementClickListener;
onElementOver: ((tooltip: TooltipData) => void) & IAction;
onElementOut: (() => void) & IAction;
Expand All @@ -24,7 +30,7 @@ interface AreaGeometriesDataState {
export class AreaGeometries extends React.PureComponent<
AreaGeometriesDataProps,
AreaGeometriesDataState
> {
> {
static defaultProps: Partial<AreaGeometriesDataProps> = {
animated: false,
num: 1,
Expand Down Expand Up @@ -86,45 +92,45 @@ export class AreaGeometries extends React.PureComponent<
[] as JSX.Element[],
);
}
private renderPoints = (points: PointGeometry[], i: number): JSX.Element[] => {
const { style } = this.props;
private renderPoints = (areaPoints: PointGeometry[], i: number): JSX.Element[] => {
const { radius, stroke, strokeWidth } = this.props.style.point;
const { overPoint } = this.state;

return points.map((point, index) => {
const { x, y, color, value, transform } = point;
return areaPoints.map((areaPoint, index) => {
const { x, y, color, value, transform } = areaPoint;
return (
<Group key={`point-${i}-${index}`}>
<Circle
x={transform.x + x}
y={y}
radius={style.dataPointsRadius * 2.5}
radius={radius * 2.5}
onClick={this.onElementClick(value)}
onMouseOver={this.onOverPoint(point)}
onMouseOver={this.onOverPoint(areaPoint)}
onMouseLeave={this.onOutPoint}
fill={'gray'}
opacity={overPoint === point ? 0.3 : 0}
opacity={overPoint === areaPoint ? 0.3 : 0}
/>
<Circle
x={transform.x + x}
y={y}
radius={style.dataPointsRadius}
radius={radius}
strokeWidth={0}
fill={color}
opacity={overPoint === point ? 0.5 : 0}
opacity={overPoint === areaPoint ? 0.5 : 0}
strokeHitEnabled={false}
listening={false}
perfectDrawEnabled={true}
/>
<Circle
x={transform.x + x}
y={y}
radius={style.dataPointsRadius}
onMouseOver={this.onOverPoint(point)}
radius={radius}
onMouseOver={this.onOverPoint(areaPoint)}
onMouseLeave={this.onOutPoint}
fill={'transparent'}
stroke={style.dataPointsStroke}
strokeWidth={style.dataPointsStrokeWidth}
opacity={overPoint === point ? 1 : 0}
stroke={stroke}
strokeWidth={strokeWidth}
opacity={overPoint === areaPoint ? 1 : 0}
strokeHitEnabled={false}
listening={false}
perfectDrawEnabled={true}
Expand All @@ -135,11 +141,15 @@ export class AreaGeometries extends React.PureComponent<
}

private renderAreaGeoms = (): JSX.Element[] => {
const { areas } = this.props;
const { areas, sharedStyle } = this.props;
return areas.map((glyph, i) => {
const { area, color, transform, geometryId } = glyph;

const geometryStyle = getGeometryStyle(geometryId, this.props.highlightedLegendItem);
const geometryStyle = getGeometryStyle(
geometryId,
this.props.highlightedLegendItem,
sharedStyle,
);

if (this.props.animated) {
return (
Expand All @@ -152,24 +162,14 @@ export class AreaGeometries extends React.PureComponent<
fill={color}
listening={false}
{...geometryStyle}
// areaCap="round"
// areaJoin="round"
/>
)}
</Spring>
</Group>
);
} else {
return (
<Path
key={`area-${i}`}
data={area}
fill={color}
listening={false}
{...geometryStyle}
// areaCap="round"
// areaJoin="round"
/>
<Path key={`area-${i}`} data={area} fill={color} listening={false} {...geometryStyle} />
);
}
});
Expand Down
Loading

0 comments on commit 766f1ad

Please sign in to comment.