;
19 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
20 | type OuterComponentProps = ObjectExclude
;
21 |
22 | export const withLeafletMap =
23 | () =>
24 |
(
25 | Component: React.ComponentType
,
26 | ): React.ComponentType<
27 | React.ClassAttributes & OuterComponentProps
28 | > => {
29 | const forwardRef: React.ForwardRefRenderFunction<
30 | typeof Component,
31 | OuterComponentProps
32 | > = (innerProps, ref) => {
33 | const ComponentAny = Component as any;
34 | return (
35 |
36 | {map =>
37 | !map ? null : (
38 |
39 | )
40 | }
41 |
42 | ) as any;
43 | };
44 |
45 | const name = Component.displayName || Component.name;
46 | forwardRef.displayName = `withLeafletMap(${name})`;
47 |
48 | return React.forwardRef>(
49 | forwardRef,
50 | ) as any;
51 | };
52 |
--------------------------------------------------------------------------------
/style/settings.scss:
--------------------------------------------------------------------------------
1 | $z-index-overlay: 200;
2 | $z-index-toast-layer: 150;
3 | $z-index-menu-layer: 100;
4 | $z-index-top-layer: 100;
5 | $z-index-sub-layer: 80;
6 | $top-bar-height: 3em;
7 | $post-top-bar-height: 3em;
8 | $channel-top-bar-height: 3em;
9 | $bottom-bar-height: 3em;
10 | $bar-shadow: 0 0 6px 3px rgb(0 0 0 / 16%), 0 0 6px 3px rgb(0 0 0 / 23%);
11 | $menu-shadow: 0 0 6px rgb(0 0 0 / 16%), 0 0 6px rgb(0 0 0 / 23%);
12 | $toast-shadow: 0 0 6px rgb(0 0 0 / 16%), 0 0 6px rgb(0 0 0 / 23%);
13 | $button-shadow: 0 5px 5px rgb(0 0 0 / 16%);
14 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "sourceMap": true,
5 | "strict": true,
6 | "noImplicitReturns": true,
7 | "noUnusedLocals": true,
8 | "noFallthroughCasesInSwitch": true,
9 | "importHelpers": true,
10 | "downlevelIteration": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "module": "esNext",
14 | "moduleResolution": "node",
15 | "target": "es6",
16 | "lib": ["es2017", "dom"],
17 | "jsx": "react",
18 | "types": ["webpack-env"],
19 | "baseUrl": ".",
20 | "paths": {
21 | "*": ["typings/*"]
22 | }
23 | },
24 | "include": ["./src/**/*"],
25 | "exclude": ["./src/sw.ts"]
26 | }
27 |
--------------------------------------------------------------------------------
/typings/react-document-title/index.d.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export = DocumentTitle;
4 |
5 | declare namespace DocumentTitle {
6 | interface IDocumentTitleProps extends React.PropsWithChildren {
7 | title: string;
8 | }
9 | }
10 |
11 | declare class DocumentTitle extends React.Component {}
12 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 | const { CleanWebpackPlugin } = require('clean-webpack-plugin');
5 | const CopyWebpackPlugin = require('copy-webpack-plugin');
6 | const TerserPlugin = require('terser-webpack-plugin');
7 | const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
8 | const { InjectManifest } = require('workbox-webpack-plugin');
9 |
10 | module.exports = function (env, argv) {
11 | const isProduction = argv.mode === 'production';
12 | const createSourceMaps = !isProduction;
13 |
14 | return {
15 | output: {
16 | filename: isProduction ? '[name].[contenthash].js' : '[name].js',
17 | path: __dirname + '/dist',
18 | publicPath: isProduction ? '' : undefined,
19 | },
20 |
21 | // Enable sourcemaps for debugging webpack's output.
22 | devtool: createSourceMaps && 'source-map',
23 |
24 | resolve: {
25 | // Add '.ts' and '.tsx' as resolvable extensions.
26 | extensions: ['.ts', '.tsx', '.js', '.json'],
27 | mainFields: ['browser', 'module', 'jsnext:main', 'main'],
28 | },
29 |
30 | module: {
31 | rules: [
32 | // All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
33 | {
34 | test: /\.tsx?$/,
35 | loader: 'ts-loader',
36 | type: isProduction ? 'javascript/esm' : 'javascript/auto', // hotloading needs commonjs enabled
37 | },
38 | // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
39 | {
40 | enforce: 'pre',
41 | test: /\.js$/,
42 | loader: 'source-map-loader',
43 | },
44 | {
45 | test: /\.(png|jpg|gif|svg)$/,
46 | type: 'asset',
47 | },
48 | {
49 | test: /\.s?css$/,
50 | use: [
51 | isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
52 | { loader: 'css-loader', options: { sourceMap: createSourceMaps } },
53 | {
54 | loader: 'postcss-loader',
55 | options: {
56 | postcssOptions: {
57 | plugins: [require.resolve('autoprefixer')],
58 | },
59 | sourceMap: createSourceMaps,
60 | },
61 | },
62 | { loader: 'sass-loader', options: { sourceMap: createSourceMaps } },
63 | ],
64 | },
65 | {
66 | test: /\.html$/,
67 | use: [
68 | {
69 | loader: 'html-loader',
70 | options: { minimize: isProduction },
71 | },
72 | ],
73 | },
74 | ],
75 | },
76 | plugins: [
77 | new HtmlWebpackPlugin({
78 | template: 'src/index.html',
79 | }),
80 | new CopyWebpackPlugin({
81 | patterns: ['src/manifest.webmanifest'],
82 | }),
83 | ...(isProduction
84 | ? [
85 | new CleanWebpackPlugin(),
86 | new MiniCssExtractPlugin({
87 | filename: isProduction ? '[name].[contenthash].css' : '[name].css',
88 | }),
89 | new InjectManifest({
90 | swSrc: './src/sw.ts',
91 | swDest: 'sw.js',
92 | }),
93 | ]
94 | : []),
95 | ],
96 | optimization: {
97 | splitChunks: {
98 | chunks: 'all',
99 | },
100 | runtimeChunk: true,
101 | minimizer: [
102 | new TerserPlugin({
103 | parallel: true,
104 | terserOptions: {
105 | sourceMap: createSourceMaps,
106 | },
107 | }),
108 | new CssMinimizerPlugin(),
109 | ],
110 | },
111 |
112 | devServer: {
113 | static: false,
114 | },
115 | };
116 | };
117 |
--------------------------------------------------------------------------------