Skip to content

Commit b0cd696

Browse files
Ihor DykhtaIhor Dykhta
authored andcommitted
upgrade custom-theme example
Signed-off-by: Ihor Dykhta <ihordykhta@Ihors-MacBook-Pro.local>
1 parent aba1109 commit b0cd696

10 files changed

Lines changed: 109 additions & 113 deletions

File tree

examples/custom-theme/.babelrc

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

examples/custom-theme/.yarnrc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# https://yarnpkg.com/configuration/yarnrc
2+
nodeLinker: node-modules
3+
# Define the registry to use when fetching packages.
4+
npmRegistryServer: 'https://registry.yarnpkg.com'

examples/custom-theme/README.md

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,42 @@
11
# Customize kepler.gl Theme
22

3-
This example show how to customize Kepler.gl theme
4-
1. Define an object (theme) to override Kepler.gl style
5-
2. Pass the newly created object as prop to KeplerGl react component
3+
This example shows how to customize the kepler.gl theme:
64

7-
#### 1. Install
5+
1. Define an object (`theme`) to override kepler.gl styles
6+
2. Pass the newly created object as the `theme` prop to the `KeplerGl` component
7+
8+
## Pre-requirements
9+
10+
- [Node.js ^20.x](http://nodejs.org)
11+
- [Yarn 4.4.0](https://yarnpkg.com): See the [installation instructions][yarn-install].
12+
13+
## 1. Install Dependencies
14+
15+
Go to the `examples/custom-theme` directory and run:
816

917
```sh
10-
yarn
18+
touch yarn.lock && yarn
1119
```
1220

21+
> `touch yarn.lock` is required once to mark this directory as a standalone Yarn project,
22+
> independent of the monorepo root.
1323
14-
#### 2. Mapbox Token
15-
add mapbox access token to node env
24+
## 2. Start the App
1625

1726
```sh
18-
export MapboxAccessToken=<your_mapbox_token>
27+
yarn start
1928
```
2029

21-
#### 3. Start the app
30+
The app will be available at [http://localhost:8080](http://localhost:8080).
31+
32+
Use the checkbox in the bottom-right corner to toggle between the default and the custom (light) theme.
33+
34+
## Production Build
2235

2336
```sh
24-
yarn start
37+
yarn build
2538
```
39+
40+
The output will be in the `dist/` directory.
41+
42+
[yarn-install]: https://yarnpkg.com/getting-started/install

examples/custom-theme/esbuild.config.mjs

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,57 @@
22
// Copyright contributors to the kepler.gl project
33

44
import esbuild from 'esbuild';
5-
import {replace} from 'esbuild-plugin-replace';
65
import {dotenvRun} from '@dotenv-run/esbuild';
76
import copyPlugin from 'esbuild-plugin-copy';
87

98
import process from 'node:process';
109
import fs from 'node:fs';
10+
import path from 'node:path';
11+
import {fileURLToPath} from 'node:url';
1112
import {spawn} from 'node:child_process';
12-
import {join} from 'node:path';
1313

1414
const args = process.argv;
1515

16+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
17+
1618
const port = 8080;
1719

1820
const NODE_ENV = JSON.stringify(process.env.NODE_ENV || 'production');
1921

20-
// Ensure a single instance of React and friends to avoid invalid hook calls
21-
const ROOT_NODE_MODULES = join('..', '..', 'node_modules');
22-
const thirdPartyAliases = {
23-
react: join(ROOT_NODE_MODULES, 'react'),
24-
'react-dom': join(ROOT_NODE_MODULES, 'react-dom'),
25-
'react-redux': join(ROOT_NODE_MODULES, 'react-redux', 'lib'),
26-
'styled-components': join(ROOT_NODE_MODULES, 'styled-components'),
27-
'apache-arrow': join(ROOT_NODE_MODULES, 'apache-arrow')
28-
};
29-
3022
const config = {
3123
platform: 'browser',
3224
format: 'iife',
3325
logLevel: 'info',
34-
loader: {
35-
'.js': 'jsx',
36-
'.css': 'css',
37-
'.ttf': 'file',
38-
'.woff': 'file',
39-
'.woff2': 'file'
40-
},
26+
loader: {'.js': 'jsx', '.css': 'css'},
4127
entryPoints: ['src/main.js'],
4228
outfile: 'dist/bundle.js',
4329
bundle: true,
4430
define: {
45-
NODE_ENV,
46-
'process.env.MapboxAccessToken': JSON.stringify(process.env.MapboxAccessToken || '')
31+
NODE_ENV
4732
},
4833
plugins: [
4934
dotenvRun({
5035
verbose: true,
5136
environment: NODE_ENV,
5237
root: '../../.env'
5338
}),
54-
replace({
55-
__PACKAGE_VERSION__: '3.1.10',
56-
include: /constants\/src\/default-settings\.ts/
57-
}),
39+
// styled-components: @hubble.gl/react nests its own copy.
40+
// react-palm: several @kepler.gl/* packages nest their own copy.
41+
// Both are singletons that break when loaded more than once.
42+
{
43+
name: 'dedupe-singletons',
44+
setup(build) {
45+
build.onResolve({filter: /^(styled-components|react-palm(\/|$)|react$|react-dom$)/}, async args => {
46+
if (args.pluginData?.deduped) return;
47+
const result = await build.resolve(args.path, {
48+
resolveDir: __dirname,
49+
kind: args.kind,
50+
pluginData: {deduped: true}
51+
});
52+
return result;
53+
});
54+
}
55+
},
5856
copyPlugin({
5957
resolveFrom: 'cwd',
6058
assets: {
@@ -82,16 +80,13 @@ function openURL(url) {
8280
const result = await esbuild
8381
.build({
8482
...config,
85-
alias: thirdPartyAliases,
8683
minify: true,
8784
sourcemap: false,
8885
metafile: true,
8986
define: {
9087
...config.define,
9188
'process.env.NODE_ENV': '"production"'
92-
},
93-
drop: ['console', 'debugger'],
94-
treeShaking: true
89+
}
9590
})
9691
.catch(e => {
9792
console.error(e);
@@ -104,7 +99,6 @@ function openURL(url) {
10499
await esbuild
105100
.context({
106101
...config,
107-
alias: thirdPartyAliases,
108102
minify: false,
109103
sourcemap: true,
110104
banner: {
@@ -121,7 +115,7 @@ function openURL(url) {
121115
console.info(remoteAddress, status, `"${method} ${path}" [${timeInMS}ms]`);
122116
}
123117
});
124-
console.info(`kepler.gl custom-theme example running at ${`http://localhost:${port}`}`);
118+
console.info(`kepler.gl custom-theme example running at http://localhost:${port}`);
125119
openURL(`http://localhost:${port}`);
126120
})
127121
.catch(e => {

examples/custom-theme/package.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
{
2+
"name": "kepler-custom-theme",
3+
"version": "0.0.1",
4+
"license": "MIT",
25
"scripts": {
36
"start": "node esbuild.config.mjs --start",
47
"build": "node esbuild.config.mjs --build",
58
"start-local": "NODE_ENV=local node esbuild.config.mjs --start"
69
},
710
"dependencies": {
8-
"@kepler.gl/components": "^3.1.10",
9-
"@kepler.gl/reducers": "^3.1.10",
10-
"global": "^4.3.0",
11-
"react": "^18.2.0",
12-
"react-dom": "^18.2.0",
13-
"react-palm": "^3.3.6",
14-
"react-redux": "^8.0.5",
15-
"react-virtualized": "^9.21.0",
16-
"redux-actions": "^2.2.1",
11+
"@kepler.gl/components": "^3.3.0-alpha.6",
12+
"@kepler.gl/reducers": "^3.3.0-alpha.6",
13+
"react": "^19.0.0",
14+
"react-dom": "^19.0.0",
15+
"react-redux": "^9.1.0",
16+
"redux": "^5.0.1",
1717
"styled-components": "6.4.3"
1818
},
1919
"devDependencies": {
2020
"@dotenv-run/esbuild": "^1.5.0",
21+
"@types/node": "^20",
22+
"@types/react": "^19.0.0",
23+
"@types/react-dom": "^19.0.0",
2124
"esbuild": "^0.25.0",
2225
"esbuild-plugin-copy": "^2.1.1",
23-
"esbuild-plugin-replace": "^1.4.0"
26+
"typescript": "^5.5.0"
2427
}
2528
}

examples/custom-theme/src/app.js

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@
33

44
import React, {useEffect, useState} from 'react';
55
import styled from 'styled-components';
6-
import Window from 'global/window';
7-
import {connect} from 'react-redux';
86
import KeplerGl from '@kepler.gl/components';
97

10-
const MAPBOX_TOKEN = process.env.MapboxAccessToken; // eslint-disable-line
11-
128
const theme = {
139
sidePanelBg: '#ffffff',
1410
titleTextColor: '#000000',
@@ -43,20 +39,19 @@ const StyleSwitch = styled.div`
4339
border: 1px solid mediumseagreen;
4440
`;
4541

46-
function App() {
47-
const [customTheme, setTheme] = useState(false);
48-
const [windowDimension, setDimension] = useState({
49-
width: Window.innerWidth,
50-
height: Window.innerHeight
51-
});
52-
42+
function useWindowSize() {
43+
const [size, setSize] = useState({width: window.innerWidth, height: window.innerHeight});
5344
useEffect(() => {
54-
const handleResize = () => {
55-
setDimension({width: Window.innerWidth, height: Window.innerHeight});
56-
};
57-
Window.addEventListener('resize', handleResize);
58-
return () => Window.removeEventListener('resize', handleResize);
45+
const onResize = () => setSize({width: window.innerWidth, height: window.innerHeight});
46+
window.addEventListener('resize', onResize);
47+
return () => window.removeEventListener('resize', onResize);
5948
}, []);
49+
return size;
50+
}
51+
52+
function App() {
53+
const [customTheme, setTheme] = useState(false);
54+
const {width, height} = useWindowSize();
6055

6156
return (
6257
<div>
@@ -70,22 +65,15 @@ function App() {
7065
/>
7166
</StyleSwitch>
7267
<KeplerGl
73-
mapboxApiAccessToken={MAPBOX_TOKEN}
68+
mapboxApiAccessToken="pk.xxx.yyy"
7469
id="map"
75-
/*
76-
* Specify path to keplerGl state, because it is not mount at the root
77-
*/
7870
getState={state => state.demo.keplerGl}
79-
width={windowDimension.width}
80-
height={windowDimension.height}
71+
width={width}
72+
height={height}
8173
theme={customTheme ? theme : emptyTheme}
8274
/>
8375
</div>
8476
);
85-
// }
8677
}
8778

88-
const mapStateToProps = state => state;
89-
const dispatchToProps = dispatch => ({dispatch});
90-
91-
export default connect(mapStateToProps, dispatchToProps)(App);
79+
export default App;

examples/custom-theme/src/main.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,10 @@
33

44
import React from 'react';
55
import ReactDOM from 'react-dom/client';
6-
import document from 'global/document';
7-
import Modal from 'react-modal';
86
import {Provider} from 'react-redux';
97
import store from './store';
108
import App from './app';
119

12-
Modal.setAppElement('#root');
13-
1410
const Root = () => (
1511
<Provider store={store}>
1612
<App />

examples/custom-theme/src/reducers/index.js

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,23 @@
22
// Copyright contributors to the kepler.gl project
33

44
import {combineReducers} from 'redux';
5-
import {handleActions} from 'redux-actions';
65

76
import keplerGlReducer from '@kepler.gl/reducers';
87

9-
import {INIT} from '../actions';
10-
11-
// INITIAL_APP_STATE
128
const initialAppState = {
139
appName: 'example'
1410
};
1511

16-
// App reducer
17-
export const appReducer = handleActions(
18-
{
19-
[INIT]: state => ({
20-
...state,
21-
loaded: true
22-
})
23-
},
24-
initialAppState
25-
);
12+
function appReducer(state = initialAppState, action) {
13+
switch (action.type) {
14+
case 'INIT':
15+
return {...state, loaded: true};
16+
default:
17+
return state;
18+
}
19+
}
2620

27-
// export demoReducer to be combined in website app
2821
export default combineReducers({
29-
// mount keplerGl reducer
3022
keplerGl: keplerGlReducer,
3123
app: appReducer
3224
});

examples/custom-theme/src/store.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: MIT
22
// Copyright contributors to the kepler.gl project
33

4-
import Window from 'global/window';
54
import {combineReducers, createStore, applyMiddleware, compose} from 'redux';
65
import {enhanceReduxMiddleware} from '@kepler.gl/reducers';
76

@@ -12,12 +11,8 @@ const reducers = combineReducers({
1211
});
1312

1413
const middlewares = enhanceReduxMiddleware([]);
14+
const enhancers = applyMiddleware(...middlewares);
1515

16-
export const enhancers = [applyMiddleware(...middlewares)];
16+
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
1717

18-
const initialState = {};
19-
20-
// add redux devtools
21-
const composeEnhancers = Window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
22-
23-
export default createStore(reducers, initialState, composeEnhancers(...enhancers));
18+
export default createStore(reducers, {}, composeEnhancers(enhancers));
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
5+
"module": "ESNext",
6+
"moduleResolution": "bundler",
7+
"jsx": "react-jsx",
8+
"strict": true,
9+
"noEmit": true,
10+
"esModuleInterop": true,
11+
"skipLibCheck": true
12+
},
13+
"include": ["src"]
14+
}

0 commit comments

Comments
 (0)