Skip to content

Commit 766f1ad

Browse files
authored
feat: add dark theme (#44)
* 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.
1 parent 80112a7 commit 766f1ad

32 files changed

+922
-473
lines changed

.storybook/config.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import '@elastic/eui/dist/eui_theme_light.css';
21
import { withInfo } from '@storybook/addon-info';
32
import { withKnobs } from '@storybook/addon-knobs';
43
import { withOptions } from '@storybook/addon-options';
54
import { addDecorator, configure } from '@storybook/react';
65
import '../src/index.scss';
7-
import './style.css';
6+
import './style.scss';
7+
import { switchTheme } from './theme_service';
8+
9+
switchTheme('light');
810

911
addDecorator(
1012
withOptions({
@@ -19,6 +21,12 @@ addDecorator(
1921
withInfo({
2022
inline: true,
2123
source: false,
24+
styles: {
25+
infoBody: {
26+
marginTop: 0,
27+
marginBottom: 0,
28+
},
29+
},
2230
}),
2331
);
2432

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
@import '../node_modules/@elastic/eui/src/themes/eui/eui_colors_dark.scss';
2+
13
.story-chart {
24
background: white;
35
}
6+
.story-chart-dark {
7+
background: $euiColorEmptyShade;
8+
}
49
#root {
510
background-color: blanchedalmond;
611
}
@@ -21,3 +26,6 @@
2126
border: 1px solid gray;
2227
padding: 5px;
2328
}
29+
.Pane.vertical.Pane1 {
30+
background: red;
31+
}

.storybook/theme_service.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @ts-ignore
2+
import themeDark from '!!style-loader/useable!css-loader!@elastic/eui/dist/eui_theme_dark.css';
3+
// @ts-ignore
4+
import themeLight from '!!style-loader/useable!css-loader!@elastic/eui/dist/eui_theme_light.css';
5+
6+
export function switchTheme(theme: string) {
7+
switch (theme) {
8+
case 'light':
9+
themeDark.unuse();
10+
themeLight.use();
11+
return;
12+
case 'dark':
13+
themeLight.unuse();
14+
themeDark.use();
15+
return;
16+
}
17+
}

src/components/_legend.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
$elasticChartsLegendMaxWidth: $euiSize * 10 + $euiSize;
2-
$elasticChartsLegendMaxHeight: $euiSize * 4 + $euiSize;
1+
$elasticChartsLegendMaxWidth: $euiSize * 10;
2+
$elasticChartsLegendMaxHeight: $euiSize * 4;
33

44
.elasticChartsLegend {
55
position: absolute;

src/components/legend.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,13 @@ class LegendComponent extends React.Component<ReactiveChartProps> {
4848
let paddingStyle;
4949
if (isVertical(legendPosition)) {
5050
paddingStyle = {
51-
paddingTop: chartTheme.chart.margins.top,
52-
paddingBottom: chartTheme.chart.margins.bottom,
51+
paddingTop: chartTheme.chartMargins.top,
52+
paddingBottom: chartTheme.chartMargins.bottom,
5353
};
5454
} else {
5555
paddingStyle = {
56-
paddingLeft: chartTheme.chart.margins.left,
57-
paddingRight: chartTheme.chart.margins.right,
56+
paddingLeft: chartTheme.chartMargins.left,
57+
paddingRight: chartTheme.chartMargins.right,
5858
};
5959
}
6060
return (

src/components/react_canvas/area_geometries.tsx

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ import React from 'react';
44
import { Circle, Group, Path } from 'react-konva';
55
import { animated, Spring } from 'react-spring/konva';
66
import { LegendItem } from '../../lib/series/legend';
7-
import { AreaGeometry, GeometryValue, getGeometryStyle, PointGeometry } from '../../lib/series/rendering';
8-
import { AreaSeriesStyle } from '../../lib/themes/theme';
7+
import {
8+
AreaGeometry,
9+
GeometryValue,
10+
getGeometryStyle,
11+
PointGeometry,
12+
} from '../../lib/series/rendering';
13+
import { AreaSeriesStyle, SharedGeometryStyle } from '../../lib/themes/theme';
914
import { ElementClickListener, TooltipData } from '../../state/chart_state';
1015

1116
interface AreaGeometriesDataProps {
1217
animated?: boolean;
1318
areas: AreaGeometry[];
1419
num?: number;
1520
style: AreaSeriesStyle;
21+
sharedStyle: SharedGeometryStyle;
1622
onElementClick?: ElementClickListener;
1723
onElementOver: ((tooltip: TooltipData) => void) & IAction;
1824
onElementOut: (() => void) & IAction;
@@ -24,7 +30,7 @@ interface AreaGeometriesDataState {
2430
export class AreaGeometries extends React.PureComponent<
2531
AreaGeometriesDataProps,
2632
AreaGeometriesDataState
27-
> {
33+
> {
2834
static defaultProps: Partial<AreaGeometriesDataProps> = {
2935
animated: false,
3036
num: 1,
@@ -86,45 +92,45 @@ export class AreaGeometries extends React.PureComponent<
8692
[] as JSX.Element[],
8793
);
8894
}
89-
private renderPoints = (points: PointGeometry[], i: number): JSX.Element[] => {
90-
const { style } = this.props;
95+
private renderPoints = (areaPoints: PointGeometry[], i: number): JSX.Element[] => {
96+
const { radius, stroke, strokeWidth } = this.props.style.point;
9197
const { overPoint } = this.state;
9298

93-
return points.map((point, index) => {
94-
const { x, y, color, value, transform } = point;
99+
return areaPoints.map((areaPoint, index) => {
100+
const { x, y, color, value, transform } = areaPoint;
95101
return (
96102
<Group key={`point-${i}-${index}`}>
97103
<Circle
98104
x={transform.x + x}
99105
y={y}
100-
radius={style.dataPointsRadius * 2.5}
106+
radius={radius * 2.5}
101107
onClick={this.onElementClick(value)}
102-
onMouseOver={this.onOverPoint(point)}
108+
onMouseOver={this.onOverPoint(areaPoint)}
103109
onMouseLeave={this.onOutPoint}
104110
fill={'gray'}
105-
opacity={overPoint === point ? 0.3 : 0}
111+
opacity={overPoint === areaPoint ? 0.3 : 0}
106112
/>
107113
<Circle
108114
x={transform.x + x}
109115
y={y}
110-
radius={style.dataPointsRadius}
116+
radius={radius}
111117
strokeWidth={0}
112118
fill={color}
113-
opacity={overPoint === point ? 0.5 : 0}
119+
opacity={overPoint === areaPoint ? 0.5 : 0}
114120
strokeHitEnabled={false}
115121
listening={false}
116122
perfectDrawEnabled={true}
117123
/>
118124
<Circle
119125
x={transform.x + x}
120126
y={y}
121-
radius={style.dataPointsRadius}
122-
onMouseOver={this.onOverPoint(point)}
127+
radius={radius}
128+
onMouseOver={this.onOverPoint(areaPoint)}
123129
onMouseLeave={this.onOutPoint}
124130
fill={'transparent'}
125-
stroke={style.dataPointsStroke}
126-
strokeWidth={style.dataPointsStrokeWidth}
127-
opacity={overPoint === point ? 1 : 0}
131+
stroke={stroke}
132+
strokeWidth={strokeWidth}
133+
opacity={overPoint === areaPoint ? 1 : 0}
128134
strokeHitEnabled={false}
129135
listening={false}
130136
perfectDrawEnabled={true}
@@ -135,11 +141,15 @@ export class AreaGeometries extends React.PureComponent<
135141
}
136142

137143
private renderAreaGeoms = (): JSX.Element[] => {
138-
const { areas } = this.props;
144+
const { areas, sharedStyle } = this.props;
139145
return areas.map((glyph, i) => {
140146
const { area, color, transform, geometryId } = glyph;
141147

142-
const geometryStyle = getGeometryStyle(geometryId, this.props.highlightedLegendItem);
148+
const geometryStyle = getGeometryStyle(
149+
geometryId,
150+
this.props.highlightedLegendItem,
151+
sharedStyle,
152+
);
143153

144154
if (this.props.animated) {
145155
return (
@@ -152,24 +162,14 @@ export class AreaGeometries extends React.PureComponent<
152162
fill={color}
153163
listening={false}
154164
{...geometryStyle}
155-
// areaCap="round"
156-
// areaJoin="round"
157165
/>
158166
)}
159167
</Spring>
160168
</Group>
161169
);
162170
} else {
163171
return (
164-
<Path
165-
key={`area-${i}`}
166-
data={area}
167-
fill={color}
168-
listening={false}
169-
{...geometryStyle}
170-
// areaCap="round"
171-
// areaJoin="round"
172-
/>
172+
<Path key={`area-${i}`} data={area} fill={color} listening={false} {...geometryStyle} />
173173
);
174174
}
175175
});

0 commit comments

Comments
 (0)