Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit 5a876ea

Browse files
light / dark toggling
1 parent fbdd7a3 commit 5a876ea

File tree

9 files changed

+154
-44
lines changed

9 files changed

+154
-44
lines changed

src/SqlStreamStoreBrowser.tsx

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
import { AppBar, CssBaseline, Toolbar, Typography } from '@material-ui/core';
1+
import {
2+
AppBar,
3+
CssBaseline,
4+
IconButton,
5+
Theme,
6+
Toolbar,
7+
Typography,
8+
} from '@material-ui/core';
29
import { MuiThemeProvider } from '@material-ui/core/styles';
10+
import { SvgIconProps } from '@material-ui/core/SvgIcon';
311
import { JSONSchema7 } from 'json-schema';
4-
import React, { ComponentType } from 'react';
12+
import React, { ComponentType, createElement } from 'react';
513
import { Observable as obs } from 'rxjs';
614
import {
715
AuthorizationProvider,
@@ -11,10 +19,14 @@ import {
1119
Notifications,
1220
withAuthorization,
1321
} from './components';
14-
import { SqlStreamStore } from './components/Icons';
22+
import {
23+
LightbulbFull,
24+
LightbulbOutline,
25+
SqlStreamStore,
26+
} from './components/Icons';
1527
import { connect, createState } from './reactive';
1628
import { actions, store, Viewer } from './stream-store';
17-
import theme from './theme';
29+
import themes from './themes';
1830
import { AuthorizationProps, HalLink, HalLinks } from './types';
1931
import { mediaTypes } from './utils';
2032

@@ -39,6 +51,7 @@ interface SqlStreamStoreBrowserState {
3951
mediaType: string;
4052
_links: HalLinks;
4153
self: HalLink;
54+
theme: Theme;
4255
forms: { [rel: string]: JSONSchema7 };
4356
}
4457
const state$ = createState<SqlStreamStoreBrowserState>(
@@ -48,6 +61,7 @@ const state$ = createState<SqlStreamStoreBrowserState>(
4861
store.hal$.forms$.map(forms => ['forms', () => forms]),
4962
store.hal$.loading$.map(loading => ['loading', () => loading]),
5063
store.hal$.mediaType$.map(mediaType => ['mediaType', () => mediaType]),
64+
themes.theme$.map(theme => ['theme', () => theme]),
5165
),
5266
obs.of({
5367
_links: {},
@@ -57,6 +71,7 @@ const state$ = createState<SqlStreamStoreBrowserState>(
5771
self: {
5872
href: '',
5973
},
74+
theme: themes.defaultTheme,
6075
}),
6176
);
6277

@@ -70,13 +85,21 @@ const initialNavigation = ({ authorization }: AuthorizationProps) =>
7085
authorization,
7186
);
7287

73-
const Hero = () => (
88+
const lightbulbs: { [key: string]: ComponentType<SvgIconProps> } = {
89+
dark: LightbulbFull,
90+
light: LightbulbOutline,
91+
};
92+
93+
const Hero = ({ theme }: { theme: Theme }) => (
7494
<AppBar position={'static'}>
7595
<Toolbar>
7696
<SqlStreamStore color={'action'} />
7797
<Typography variant={'h6'} color={'inherit'}>
7898
Sql Stream Store
7999
</Typography>
100+
<IconButton onClick={() => themes.actions.type.next(void 0)}>
101+
{createElement(lightbulbs[theme.palette.type])}
102+
</IconButton>
80103
</Toolbar>
81104
</AppBar>
82105
);
@@ -85,19 +108,21 @@ const SqlStreamStoreBrowser: ComponentType<
85108
SqlStreamStoreBrowserState
86109
> = withAuthorization()(
87110
mount<SqlStreamStoreBrowserState & AuthorizationProps>(initialNavigation)(
88-
({ loading, ...props }) => (
89-
<MuiThemeProvider theme={theme}>
90-
<div>
91-
<CssBaseline />
92-
<Hero />
93-
<Loading open={loading} />
94-
<NavigationProvider onNavigate={onNavigate}>
95-
<Viewer {...props} />
96-
<Notifications />
97-
</NavigationProvider>
98-
</div>
99-
</MuiThemeProvider>
100-
),
111+
({ loading, theme, ...props }) => {
112+
return (
113+
<MuiThemeProvider theme={theme}>
114+
<div>
115+
<CssBaseline />
116+
<Hero theme={theme} />
117+
<Loading open={loading} />
118+
<NavigationProvider onNavigate={onNavigate}>
119+
<Viewer {...props} />
120+
<Notifications />
121+
</NavigationProvider>
122+
</div>
123+
</MuiThemeProvider>
124+
);
125+
},
101126
),
102127
);
103128

src/components/Hyperlink.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import { WithStyles, withStyles } from '@material-ui/core';
1+
import { Theme, WithStyles, withStyles } from '@material-ui/core';
22
import React, { ComponentType } from 'react';
3-
import theme from '../theme';
43
import { HalLink, HalLinks, NavigatableProps } from '../types';
54
import { preventDefault } from '../utils';
65
import { withNavigation } from './NavigationProvider';
76

8-
const color = theme.palette.action.active;
9-
10-
const styles = {
7+
const styles = ({
8+
palette: {
9+
action: { active: color },
10+
},
11+
}: Theme) => ({
1112
hyperlink: {
1213
'&:active': {
1314
color,
@@ -20,7 +21,7 @@ const styles = {
2021
},
2122
color,
2223
},
23-
};
24+
});
2425

2526
interface HyperlinkProps {
2627
rel: string;

src/components/Icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ export { default as SpaceBar } from '@material-ui/icons/SpaceBar';
2121
export { default as Search } from '@material-ui/icons/Search';
2222
export { default as List } from '@material-ui/icons/List';
2323
export { default as Help } from '@material-ui/icons/Help';
24+
export { LightbulbFull, LightbulbOutline } from './mui';

src/components/Icons/mui/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014 Call-Em-All
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* tslint:disable:max-line-length */
2+
import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
3+
import React from 'react';
4+
5+
const LightbulbFull = (props: SvgIconProps) => (
6+
<SvgIcon {...props}>
7+
<path
8+
d={
9+
'm9,21c0,0.55 0.45,1 1,1l4,0c0.55,0 1,-0.45 1,-1l0,-1l-6,0l0,1zm3,-19c-3.86,0 -7,3.14 -7,7c0,2.38 1.19,4.47 3,5.74l0,2.26c0,0.55 0.45,1 1,1l6,0c0.55,0 1,-0.45 1,-1l0,-2.26c1.81,-1.27 3,-3.36 3,-5.74c0,-3.86 -3.14,-7 -7,-7z'
10+
}
11+
/>
12+
</SvgIcon>
13+
);
14+
15+
export default LightbulbFull;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* tslint:disable:max-line-length */
2+
import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
3+
import React from 'react';
4+
5+
const LightbulbOutline = (props: SvgIconProps) => (
6+
<SvgIcon {...props}>
7+
<path
8+
d={
9+
'M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z'
10+
}
11+
/>
12+
</SvgIcon>
13+
);
14+
15+
LightbulbOutline.muiName = 'SvgIcon';
16+
17+
export default LightbulbOutline;

src/components/Icons/mui/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as LightbulbFull } from './LightbulbFull';
2+
export { default as LightbulbOutline } from './LightbulbOutline';

src/theme.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/themes.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { createMuiTheme, PaletteType, Theme } from '@material-ui/core';
2+
import { PaletteOptions } from '@material-ui/core/styles/createPalette';
3+
import { Observable } from 'rxjs';
4+
import { createAction, createState } from './reactive';
5+
6+
const palette = (type: PaletteType): PaletteOptions => ({
7+
action: {
8+
active: '#42c0fb',
9+
},
10+
type,
11+
});
12+
13+
const typography = {
14+
useNextVariants: true,
15+
};
16+
17+
const createTheme = (type: PaletteType) =>
18+
createMuiTheme({
19+
palette: palette(type),
20+
typography,
21+
});
22+
23+
const actions = {
24+
type: createAction<void>(),
25+
};
26+
27+
const defaultTheme = createTheme('light');
28+
29+
interface ThemeState {
30+
theme: Theme;
31+
}
32+
33+
const theme$ = createState<ThemeState>(
34+
actions.type.map(() => [
35+
'theme',
36+
({ palette: { type } }: Theme) =>
37+
createTheme(type === 'light' ? 'dark' : 'light'),
38+
]),
39+
Observable.of({
40+
theme: defaultTheme,
41+
}),
42+
).map(({ theme }) => theme);
43+
44+
export default {
45+
actions,
46+
defaultTheme,
47+
theme$,
48+
};

0 commit comments

Comments
 (0)