@opengeoweb/theme 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +458 -65
  2. package/index.d.ts +1 -1
  3. package/lib/components/Theme/ThemeContext.d.ts +17 -0
  4. package/{theme.test.d.ts → lib/components/Theme/ThemeContext.spec.d.ts} +1 -1
  5. package/lib/components/Theme/darkTheme.d.ts +3 -0
  6. package/{theme.d.ts → lib/components/Theme/gwTheme.d.ts} +7 -7
  7. package/lib/components/Theme/index.d.ts +5 -0
  8. package/lib/components/Theme/lightTheme.d.ts +3 -0
  9. package/lib/components/Theme/types.d.ts +121 -0
  10. package/lib/components/Theme/utils.d.ts +7 -0
  11. package/lib/components/Theme/utils.spec.d.ts +1 -0
  12. package/lib/stories/Backdrop.stories.d.ts +8 -0
  13. package/lib/stories/Card.stories.d.ts +3 -0
  14. package/lib/stories/Colors.stories.d.ts +7 -0
  15. package/lib/stories/Elevation.stories.d.ts +3 -0
  16. package/lib/stories/FormElements.stories.d.ts +4 -0
  17. package/lib/stories/List.stories.d.ts +3 -0
  18. package/lib/stories/Slider.stories.d.ts +3 -0
  19. package/lib/stories/StoryWrapper.d.ts +9 -0
  20. package/lib/stories/Table.stories.d.ts +3 -0
  21. package/lib/stories/Tabs.stories.d.ts +8 -0
  22. package/lib/stories/Tooltip.stories.d.ts +7 -0
  23. package/lib/stories/Typography.stories.d.ts +4 -0
  24. package/lib/stories/index.stories.d.ts +15 -0
  25. package/lib/stories/snapshots/Backdrop.stories.d.ts +17 -0
  26. package/lib/stories/snapshots/Card.stories.d.ts +17 -0
  27. package/lib/stories/snapshots/Colors.stories.d.ts +17 -0
  28. package/lib/stories/snapshots/Elevation.stories.d.ts +17 -0
  29. package/lib/stories/snapshots/FormElements.stories.d.ts +7 -0
  30. package/lib/stories/snapshots/List.stories.d.ts +7 -0
  31. package/lib/stories/snapshots/Slider.stories.d.ts +7 -0
  32. package/lib/stories/snapshots/Table.stories.d.ts +17 -0
  33. package/lib/stories/snapshots/Tabs.stories.d.ts +7 -0
  34. package/lib/stories/snapshots/Tooltip.stories.d.ts +17 -0
  35. package/lib/stories/snapshots/Typography.stories.d.ts +7 -0
  36. package/lib/storyshots/Storyshots.spec.d.ts +1 -0
  37. package/package.json +11 -121
  38. package/theme.esm.js +1196 -0
  39. package/theme.umd.js +1175 -0
  40. package/AUTHORS +0 -14
  41. package/LICENCE +0 -13
  42. package/index.js +0 -13
  43. package/theme.js +0 -215
  44. package/theme.stories.d.ts +0 -7
  45. package/theme.stories.js +0 -257
  46. package/theme.test.js +0 -44
package/README.md CHANGED
@@ -1,115 +1,508 @@
1
- [![pipeline status](https://gitlab.com/opengeoweb/geoweb-theme/badges/master/pipeline.svg)](https://gitlab.com/opengeoweb/geoweb-theme/-/commits/master)
2
- [![current version](https://img.shields.io/badge/dynamic/json?color=blue&label=version&query=version&url=https://gitlab.com/opengeoweb/geoweb-theme/raw/master/package.json)](https://gitlab.com/opengeoweb/geoweb-theme/-/tags)
1
+ # Theme
2
+
3
+ The aim of this library is to make sure all MUI components look as specified in the designs found on Zeplin. There are multiple themes (dark and light) with color and stying which can be added and all values are accessible throughout the whole application.
4
+
5
+ ## Content
6
+
7
+ - [Quick start](#quick-start)
8
+ - [Running storybook](#running-storybook)
9
+ - [Adding styles/colors](#adding-styles-colors)
10
+ - [Using styles/colors to (React/MUI) components](#using-styles-colors-to--react-mui--components)
11
+ - [Using styles/colors in canvas components](#using-styles-colors-in-non--canvas--mui-components)
12
+ - [Using themes in stories](#using-themes-in-stories)
13
+ - [Rules of theme lib](#rules-of-theme-lib)
14
+ - [Folder structure](#folder-structure)
15
+ - [types `(lib/components/Theme/types.ts)`](#types---lib-components-theme-typests--)
16
+ - [themes `(lib/components/Theme/darkTheme.ts, .../lightTheme.ts, .../gwTheme.ts)`](#themes---lib-components-theme-darkthemets---lightthemets---gwthemets--)
17
+ - [ThemeContext `(lib/components/Theme/ThemeContext)`](#themecontext---lib-components-theme-themecontext--)
18
+ - [utils `(lib/components/Theme/utils.ts)`](#utils---lib-components-theme-utilsts--)
19
+ - [stories `(lib/stories)`](#stories---lib-stories--)
20
+ - [Naming convention](#naming-convention)
21
+ - [Theme Stories `(lib/stories)`](#theme-stories---lib-stories--)
22
+ - [Overwrite default MUI component styling](#overwrite-default-mui-component-styling)
23
+ - [important note about Material UI v5](#important-note-about-material-ui-v5)
24
+ - [Guidelines and tips for translating design to code](#guidelines-and-tips-for-translating-design-to-code)
25
+ - [Layer manager example](#layer-manager-example)
26
+ - [Wrapper](#wrapper)
27
+ - [Top bar](#top-bar)
28
+ - [Table](#table)
29
+ - [Footer](#footer)
30
+ - [Do's and dont's](#do-s-and-dont-s)
31
+ - [Do's](#do-s)
32
+ - [Don'ts](#don-ts)
33
+ - [Known issues](#known-issues)
34
+ - [Roadmap](#roadmap)
35
+ - [Unit testing](#unit-testing)
36
+ - [Image snapshot testing](#image-snapshot-testing)
37
+ - [Add a new snapshot test](#add-a-new-snapshot-test)
38
+ - [Running snapshot tests and updating snapshots locally](#running-snapshot-tests-and-updating-snapshots-locally)
39
+ - [Questions and feedback](#questions-and-feedback)
40
+ - [Documentation](#documentation)
41
+
42
+ <small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
43
+
44
+ ## Quick start
45
+
46
+ ### Running storybook
3
47
 
4
- # KNMI GeoWeb Theme
48
+ ```
49
+ nx storybook theme
50
+ ```
51
+
52
+ ### Adding styles/colors
53
+
54
+ 1. Add the name and type on the GeowebColorPalette type
55
+
56
+ ```javascript
57
+ // libs/theme/src/lib/components/Theme/types.ts
58
+ export type GeowebColorPalette = {
59
+ buttons: {
60
+ primaryMouseOver: CSSProperties,
61
+ },
62
+ // ... rest of type
63
+ };
64
+ ```
65
+
66
+ 2. Add the style/color values in lightTheme and darkTheme
67
+
68
+ ```javascript
69
+ /// libs/theme/src/lib/components/Theme/lightTheme.ts
70
+ export const colors: GeowebColorPalette = {
71
+ buttons: {
72
+ primaryMouseOver: {
73
+ fill: '#186DFF',
74
+ border: '#71A6FF',
75
+ },
76
+ },
77
+ ```
78
+
79
+ 3. Verify it works by navigating to the Color story demo and see the new colors work in all themes. Every property you fill in is accessible throughout every app or library.
80
+
81
+ ### Using styles/colors to (React/MUI) components
82
+
83
+ 1. Make sure the theme ThemeProvider is used
84
+
85
+ ```javascript
86
+ import { ThemeProvider } from '@opengeoweb/theme';
87
+
88
+ export const Wrapper: React.FC = () => (
89
+ <ThemeProvider>
90
+ <MyComponent />
91
+ </ThemeProvider>
92
+ );
93
+ ```
94
+
95
+ > **note** make sure to use the ThemeProvider in unit tests too, as they will fail otherwise
96
+
97
+ 2. Use the style/color in your component. The theme palette can be found as `geowebColor` property inside the `theme.palette` of the MUI Theme
98
+
99
+ ```javascript
100
+ const useStyles = makeStyles((theme) => ({
101
+ button: {
102
+ border: theme.palette.geowebColors.buttons.flatMouseOver.border,
103
+ '&:hover': {
104
+ backgroundColor: theme.palette.geowebColors.buttons.flatMouseOver.fill,
105
+ },
106
+ },
107
+ }));
108
+
109
+ const MyButton: React.FC = () => {
110
+ const classes = useStyles();
111
+ return <Button className={classes.button}>content</Button>;
112
+ };
113
+ ```
114
+
115
+ ### Using styles/colors in canvas components
116
+
117
+ Since the color values are depending on the current selected theme, we can't use a static object for color values. A simple solution for this is to access the theme via `useTheme` hook selector, and pass it as a param to the canvas drawing function.
118
+
119
+ 1. Use `useTheme` selector and pass theme as argument to the draw method:
120
+
121
+ ```javascript
122
+ // libs/core/src/lib/components/TimeSlider/TimeSliderLegend/TimeSliderLegend.tsx
123
+ const TimeSliderLegend: React.FC<TimeSliderLegendProps> = (
124
+ props: TimeSliderLegendProps,
125
+ ) => {
126
+ const theme = useTheme();
127
+ return (
128
+ <div>
129
+ <CanvasComponent
130
+ onRenderCanvas={(ctx: CanvasRenderingContext2D): void => {
131
+ renderTimeSliderLegend(
132
+ ctx,
133
+ theme,
134
+ // ...props and other methods
135
+ );
136
+ }}
137
+ />
138
+ </div>
139
+ );
140
+ };
141
+ ```
142
+
143
+ 2. Extend the render method with theme as argument, and pass if necessary the theme further to the other render methods. Most easy way is to just pass the whole theme as object, so you can use the `Theme` type from MUI.
144
+
145
+ ```javascript
146
+ // libs/core/src/lib/components/TimeSlider/TimeSliderLegend/TimeSliderLegendRenderFunctions.tsx
147
+ import { Theme } from '@material-ui/core';
148
+
149
+ export const renderTimeSliderLegend = (
150
+ context: CanvasRenderingContext2D,
151
+ theme: Theme,
152
+ canvasWidth: number,
153
+ height: number,
154
+ centerTime: number,
155
+ secondsPerPx: number,
156
+ dataScaleToSecondsPerPx: number,
157
+ selectedTimeUnix: number,
158
+ scale: Scale,
159
+ currentTimeUnix: number,
160
+ ): void => {
161
+ const ctx = context;
162
+
163
+ drawBackground(
164
+ ctx,
165
+ theme,
166
+ visibleTimeStart,
167
+ visibleTimeEnd,
168
+ canvasWidth,
169
+ height,
170
+ scale,
171
+ );
172
+ ```
173
+
174
+ 3. Use the color (or any other given property) by deconstructing the passed theme if needed, and if needed use the `rgba` property.
175
+
176
+ ```javascript
177
+ // libs/core/src/lib/components/TimeSlider/TimeSliderLegend/TimeSliderLegendRenderFunctions.tsx
178
+ const drawBackground = (
179
+ context: CanvasRenderingContext2D,
180
+ theme: Theme,
181
+ visibleTimeStart: number,
182
+ visibleTimeEnd: number,
183
+ canvasWidth: number,
184
+ height: number,
185
+ scale: Scale,
186
+ ): void => {
187
+ const ctx = context;
188
+ const { timelineTimelineSurface, timelineNightTime} = theme.palette.geowebColors.timeSlider
189
+
190
+ ctx.fillStyle = isColorIntervalEven(scale, timestep)
191
+ ? timelineTimelineSurface.rgba
192
+ : timelineNightTime.rgba;
193
+ });
194
+ };
195
+ ```
196
+
197
+ ### Using themes in stories
198
+
199
+ When using a component which relies on theme styling, wrap the main component of your story with the `ThemeWrapper` component instead of `ThemeProvider`. `ThemeWrapper` will later get an extra `StyleEngineProvider` parent component (see https://mui.com/guides/migration-v4/#style-library). For components with old GWTheme styline, you can use `ThemeWrapperOldTheme`.
200
+
201
+ If you need to show multiple stories and don't want to see the default background, use the `disableCssBaseline` property to prevent that.
202
+
203
+ ```javascript
204
+ import { darkTheme, ThemeWrapper } from '../../components/Theme';
205
+
206
+ export const TableDark = (): React.ReactElement => (
207
+ <ThemeWrapper theme={darkTheme}>
208
+ <TableDemo />
209
+ </ThemeWrapper>
210
+ );
211
+ ```
212
+
213
+ ## Rules of theme lib
214
+
215
+ - The theme should not export any other component then the themes, ThemeProvider and corresponding hooks. This lib is only showing the MUI components with the correct default style. If you need a component which needs custom props and should be used across different applications, consider making a new component in the `shared` lib.
216
+ - It should not import other any library other then MUI.
217
+
218
+ ## Folder structure
219
+
220
+ ```
221
+ // lib/components
222
+ // lib/components/Theme/darkTheme.ts
223
+ // lib/components/Theme/lighTheme.ts
224
+ // lib/components/Theme/gwTheme.ts
225
+ // lib/components/Theme/utils.ts
226
+ // lib/components/Theme/types.ts
227
+ // lib/components/Theme/ThemeContext.tsx
228
+
229
+ // lib/stories
230
+ // lib/stories/StoryWrapper.tsx
231
+ // lib/stories/story.stories.tsx
232
+ ```
233
+
234
+ #### types `(lib/components/Theme/types.ts)`
235
+
236
+ Defines the color palette of the theme.
237
+
238
+ #### themes `(lib/components/Theme/darkTheme.ts, .../lightTheme.ts, .../gwTheme.ts)`
239
+
240
+ Exports files containing all the values per theme. Every color added to light or dark will automatically be inserted into gwTheme to maintain backwards compatibility while finishing the theme colors.
241
+
242
+ #### ThemeContext `(lib/components/Theme/ThemeContext)`
243
+
244
+ - exports `ThemeProvider` wrapper for all MUI components including a `CssBaseline` component of MUI.
245
+ - exports an `useThemeContext` to switch themes.
246
+ - exports `ThemeWrapper` wrapper for stories and `ThemeWrapperOldTheme` wrapper for stories with old GWTheme (to be deprecated)
247
+
248
+ #### utils `(lib/components/Theme/utils.ts)`
5
249
 
6
- ### Installation
250
+ - **hex2rgba** handles hex values to rgba
251
+ - **parseColors** parses the theme values and when opacity and fill are given, adds a rgba value. This is handy for canvas components, as they expect one value to render a fill.
7
252
 
8
- To run the KNMI Theme storybook you need npm. The easiest way to install npm is via nvm. Please visit https://nvm.sh/ and follow the instructions. When nvm is installed, please run the following command:
253
+ If in future another parser is needed (for example a font parser: when fontSize and fontFamily is given, return font which combines those values), it can be added here,
9
254
 
255
+ - **createShadows** creates a list of shadows (elevations) as specified by design . These can be accessed through the theming by `theme.shadows`.
256
+ - **createTheme** function that creates the theme with given colors and shadows. This also override default MUI components. It sets the values of the theme as `geowebColors` inside the palette of the MUI Theme.
257
+
258
+ #### stories `(lib/stories)`
259
+
260
+ Contains demos of MUI components within the theme. [More information](#theme-stories---lib-stories--)
261
+
262
+ ## Naming convention
263
+
264
+ When adding a new color, it needs to follow the names provided by design. It follows the pattern segmentName.elementName.value or segmentName.elementName.elementProp1.value.
265
+
266
+ ![naming convention](src/lib/docs/namingConvention.png?raw=true)
267
+
268
+ If you look at the example above, you can see two segments: Background and Buttons. Backgrounds don't need much properties other then fill, so we don't need deep value. Buttons on the other hand have next to a fill a border, so it makes sense to specify it a bit more:
269
+
270
+ ```javascript
271
+ // lib/components/Theme/lightTheme.ts
272
+ background: {
273
+ surface: '#FFFFFF',
274
+ surfaceApp: '#F5F5F5',
275
+ surfaceBrowser: '#CFCFCF',
276
+ },
277
+ buttons: {
278
+ primary: {
279
+ fill: '#F186DFF',
280
+ border: 'none',
281
+ },
282
+ tertiary: {
283
+ fill: 'none',
284
+ border: '#0075A9',
285
+ }
286
+ }
10
287
  ```
11
- nvm install 12
288
+
289
+ Some Components have more colors sections. Take a look at some of the colors of the Timeslider.
290
+ ![enter image description here](src/lib/docs/timesliderColors.png?raw=true)
291
+
292
+ > **Note:** Some color names have (D) after their name (currently only in Dark theme). This means the color already defined in the main Color Palette and you don't have to define it again.
293
+
294
+ The segment is TimeSlider, and a sub segment is Player and Time scale. We don't want to create another level of depth so we solve this by adding this 'sub segment' as a prefix to the name of the element.
295
+
296
+ ```javascript
297
+ // lib/components/Theme/darkTheme.ts
298
+ timeSlider: {
299
+ playerNeedlePlayerTop: {
300
+ fill: '#E3004F',
301
+ opacity: 100,
302
+ },
303
+ timeScaleText: {
304
+ fontSize: 12,
305
+ },
306
+ timeScaleTimeIndicatiors: {
307
+ fill: '#A2A2A2',
308
+ },
309
+ },
12
310
  ```
13
311
 
14
- ### To run the storybook
312
+ > **Note:** fill is often used for elements but color for example is also possible for font elements
313
+
314
+ If there are mistakes in naming, colors are missing in the Design, contact [Didier](https://gitlab.com/didier.dezanet). Other way around as well, if any names have been changed [Didier](https://gitlab.com/didier.dezanet) should create a ticket to fix it here as well to keep consistency.
15
315
 
316
+ ## Theme Stories `(lib/stories)`
317
+
318
+ Contains demo stories with MUI components. Every story is build with the `StoryWrapper` component which needs links to the designs (`lib/stories/StoryWrapper.tsx`) and can be toggled from light to dark theme. It does not export anything, it only shows the MUI components in light or dark theme.
319
+
320
+ - The **Color** story shows all the colors, styles and other properties of the defined theme. Could be handy for reviewing styling values. On the right the `geowebColor` object is shown, and these values are accessible throughout all components with the ThemeProvider wrapper. Not that more values are shown than given, this is because of the parsers that adds in some cases extra properties as for example `rgba`
321
+ - The **Elevation** shows all elevations we currently have. These can be used for defining `box-shadow` for elements. If you want to use the elevation in code:
322
+
323
+ ```javascript
324
+ const useStyles = makeStyles((theme) => ({
325
+ header: {
326
+ boxShadow: theme.shadows[1], // elevation_01
327
+ },
328
+ }));
16
329
  ```
17
- npm ci
18
- npm run storybook
330
+
331
+ - The rest of the stories are for showing the MUI elements without any styling, other then the given theme styling.
332
+
333
+ ### Overwrite default MUI component styling
334
+
335
+ When developing and using a new component of the MUI library which has no theme story, it could be a good idea to create a story, add the component there, and add some theme styling. That way there is a clear example how the component will look in the MUI environment.
336
+
337
+ In the function below `createTheme` takes the value of theme and shadows (elevation) and creates the theme. Some default components are overwritten as MuiCssBaseline and MuiRadio with given theme styling.
338
+
339
+ ```javascript
340
+ // libs/theme/src/lib/components/Theme/utils.ts
341
+ export const createTheme = (
342
+ paletteType: PaletteType,
343
+ geowebColors: GeowebColorPalette,
344
+ shadows: Shadows,
345
+ ): Theme =>
346
+ createMuiTheme({
347
+ palette: {
348
+ background: {
349
+ paper: geowebColors.background.surfaceApp,
350
+ default: geowebColors.background.surfaceBrowser,
351
+ },
352
+ text: {
353
+ primary: geowebColors.typographyAndIcons.text,
354
+ },
355
+ // geoweb color palette
356
+ geowebColors,
357
+ },
358
+ shape: { borderRadius: BORDER_RADIUS },
359
+ typography: {
360
+ fontFamily: ['Roboto', 'Helvetica', 'Arial', 'sans-serif'].join(','),
361
+ },
362
+ shadows,
363
+ overrides: {
364
+ MuiCssBaseline: {
365
+ '@global': {
366
+ body: {
367
+ fontSmoothing: 'auto',
368
+ },
369
+ },
370
+ },
371
+ MuiRadio: {
372
+ root: {
373
+ color: geowebColors.typographyAndIcons.iconLinkActive,
374
+ },
375
+ },
376
+ }
19
377
  ```
20
378
 
21
- ### Storybook
379
+ > **Note:** when you add or change a style of a MUI component, every component will look default that way. If you need for example need some more custom styling or props, consider creating a reusable component in the `shared` library. Remember this library does not export components.
380
+
381
+ ## important note about Material UI v5
382
+
383
+ Material UI v5 is just around the corner. This will making theming much easier with for example the possibility of [adding custom variants](https://next.material-ui.com/customization/theme-components/#adding-new-component-variants).
384
+
385
+ For example, take a look in the designs of the [Buttons]. (https://app.zeplin.io/project/5ecf84a3c6ae1047a368f393/screen/5ecf85c60f301e47ca4eee55) There are multiple variants of the Button specified, but the MUI Button only accepts the default variant names supplied by MUI (contained, outlined, text). In future we could add custom new variants as primary, secondary and tertiary.
386
+
387
+ If you want to have a reusable Button in this case there are two options:
388
+
389
+ - Create a Button story in `theme` lib, add some buttons with variants of props that are matching with design. For example `<Button variant='filled' color="primary" />`. You probably need some overriding of styles so that can be added in `createTheme` at the override section. This is not ideal, as the it's still a bit of matching and combining with props, and not all names of design we can add.
390
+ - Create a Button story in `shared` lib, import the Button of MUI, and add there all the (custom) variants you need. Colors and style can be retrieved by `useTheme` hook selector, this is a better solution as it won't break anything, and you name all props like provided in design to keep it consistent.
22
391
 
23
- #### Inspecting the components with storybook
392
+ ## Guidelines and tips for translating design to code
24
393
 
25
- Storybook can be used to view the components. If you run `npm run storybook` a storybook server will start in which you can see all the components for which stories are written.
394
+ The designs found in Zeplin can roughly be split in two:
26
395
 
27
- #### Writing a new story
396
+ 1. Components
397
+ - Base components following MUI names as Container, Buttons, Elevation, Cards, Elevation, Table
398
+ - Grouped components combining Base components as Header, Top Bar
399
+ 2. Modules
400
+ - TimeSlider, Sigmet, LayerManager etc
28
401
 
29
- Stories live in the stories folder. Here is the documentation on the syntax for adding new stories:
30
- https://storybook.js.org/docs/basics/writing-stories/
402
+ ### Layer manager example
31
403
 
32
- #### Deploying a static version of your storybook
404
+ In this example, we're going to have a look at the Layer manager.
405
+ ![enter image description here](src/lib/docs/layerManager.png?raw=true)
33
406
 
34
- The storybook can be compiled to a static version via npm run build-storybook. The static contents are then placed in the folder storybook-geoweb-core.
407
+ Looking at the design, we can see it's consisting mainly out these elements:
35
408
 
36
- ### Managing packages
409
+ - Wrapper
410
+ - Top bar
411
+ - Table
412
+ - Footer
37
413
 
38
- Follow the instructions below for dependency management. Please refer to [the documentation](https://docs.npmjs.com/cli-documentation/) for more information on any of the specific commands.
414
+ #### Wrapper
39
415
 
40
- #### Removing extraneous packages
416
+ This is the first component which holds all sub components which compose the Layermanager. Looking it from a MUI perspective, the first element should be a Paper because it's a surface, and has the background name `Background Surface app`. The box-shadow is a side effect of elevation, the higher the elevation, the more shadow. Elevation is a default property of Paper, and since the elevations are also defined in the theme we can use those.
41
417
 
42
- During development, we may end up with packages that have been installed but are not actually being used. In order to remove them, run `npm prune`.
418
+ #### Top bar
43
419
 
44
- #### Adding a new dependency
420
+ If you look at the header and forget the left group, you can see it's a header that is used on multiple places like Sigmet dialog header, LayerManager and MultiDimensionSelect but in different sizes. It makes sense to create a reusable component in the `shared` library with a property size to ensure all sizes work correctly.
45
421
 
46
- Adding a new dependency can be done following these steps:
422
+ > link to design: https://app.zeplin.io/project/5ecf84a3c6ae1047a368f393/screen/60f9319044360a123ca42552
47
423
 
48
- 1. `npm install <package-name>` or `npm install <package-name> --save-dev`
49
- 2. commit the updated files package.json and package-lock.json
424
+ #### Table
50
425
 
51
- Make sure to add the package as a dev depencency when it's only used for development purposes (like storybook or linting).
426
+ The elements of the layermanager are build on top of the table design. In this case, it would make sense to create a new Table\* story in the `theme` library. There we make a story where we are using the MUI Table components, and make sure it has all the correct colors and styling. When that is working correctly, we can use the Table component everywhere and it will look the same everywhere.
52
427
 
53
- #### Updating an existing dependency
428
+ Every row renders columns with different inputs; for example for the layers list we can use the MUI `MenuItem` component. It would make sense to create a separate story for `MenuItem`, and make sure all base colors are correct.
54
429
 
55
- To see a list of which packages could need updating, run `npm outdated -l`.
56
- A red package name means there’s a newer version matching the semver requirements in the package.json, so it can be updated. Yellow indicates that there’s a newer version higher than the semver requirements in the package.json (usually a new major version), so proceed with caution.
430
+ By wrapping them all together, there's probably some additional styling needed specific for the LayerManager but that's perfectly fine (it can be done in for example the `Wrapper` described above). The goal is that the `MenuItem` and `Table` will have a good default look to use in other places as well.
57
431
 
58
- To update a single package to its latest version that matches the version required in package.json (red in the list), run `npm update <package-name>`, and commit the updated package-lock.json file.
432
+ > link to design: https://app.zeplin.io/project/5ecf84a3c6ae1047a368f393/screen/6093e69005029c358090bd4e
59
433
 
60
- To update all packages at once (that are red in the list), run `npm update`, and commit the updated package-lock.json file.
434
+ > **\*note** it's a assumption the Table component will work for the LayerManager. Currently there's a small story demo that shows's the styling so far, but not with for example max-height functionality. This is possible with adding `position:sticky` to the `th` elements, but needs further investigation if this component can fully suit our needs.
61
435
 
62
- To update a single package to a version higher than the required version in package.json (yellow in the list):
436
+ #### Footer
63
437
 
64
- 1. check if there are any breaking changes to be aware of in the new version
65
- 2. `npm install <package-name>@<version>` or `npm install <package-name>@<version> --save-dev`
66
- 3. commit the updated files package.json and package-lock.json
67
- 4. update the code related to breaking changes
438
+ This footer is only used for when the wrapper is resizable. Therefore it would make sense to make it part of a Resizable component. It can use the default values from the theme by using `useTheme` hook.
68
439
 
69
- After any version change, make sure to test if everything still works.
440
+ ## Do's and dont's
70
441
 
71
- #### Checking for vulnerabilities
442
+ ### Do's
72
443
 
73
- To scan the project for any known vulnerabilities in existing dependencies, you can run `npm audit`. To fix them:
444
+ - do follow design names, if you feel the name has too much repeat in it or can be changed, ask [Didier](https://gitlab.com/didier.dezanet)! Same for missing colors .
445
+ - do add links to design in code
446
+ - do create shared components that are used in knmi-geoweb and reference application in the `shared` lib
447
+ - do add a ThemeProvider for components with a new theme styling. Otherwise unit tests will break
448
+ - do discuss the library and the usage of it. If you think it can be approved please let us know!
74
449
 
75
- 1. `npm audit fix`
76
- 2. commit the updated package-lock.json
77
- 3. test if everything still works
450
+ ### Don'ts
78
451
 
79
- ### Tests
452
+ - don't add double colors (see TimeSlider example). In dark theme designs, color names suffixed with a (D) are color names defined in the main Color page.
453
+ - don't override the theme for MUI components when they are specific for a design. For example the buttons in the Timeslider don't follow the exact rules of the main Buttons, so it's a good idea to make a custom TimeSliderButton component which uses the colors defined in the theme palette.
80
454
 
81
- Tests can be run by the following command: `npm test`. This will run all the tests specified in the stories without starting a browser.
82
- In order to see a coverage report, run: `npm run test:coverage`
455
+ ## Known issues
83
456
 
84
- #### Testing the package in another project
457
+ - **React.Strictmode** does not work well with dynamic changing of themes. For now we have disabled it, but it should be activated again after the update to MUI 5. https://gitlab.com/opengeoweb/opengeoweb/-/issues/965
458
+ - **Expect unit tests to fail** when using components with the theme. This is easily fixed by wrapping your test with the `ThemeProvider` from the `theme` lib. Don't import the ThemeProvider wrapper in the failed test, but use the `CoreThemeProvider` or `CoreThemeStoreProvider` found in [`libs/core/src/lib/components/Providers/Providers.tsx`](https://gitlab.com/opengeoweb/opengeoweb/-/blob/master/libs/core/src/lib/components/Providers/Providers.tsx#L36)
459
+ - There are some **storybook bugs** with stories with Themes. When switching stories with new and old theme, it could be possible that some colors are rendered wrong. This is probably happening because one of the stories with old theme has `React.Strictmode` activated. This is only happening in storybook, and when refreshing page the colors should be correct. This will fix itself when we have `gwTheme` removed.
460
+ - **MUI 5** makes it easy to add custom variants to components, so we should wait for that release before investing more heavy in theme stories: https://next.material-ui.com/customization/theme-components/#adding-new-component-variants . Check the progress of the release of [v5 here](https://github.com/mui-org/material-ui/milestone/44)
461
+ - The `ThemeProvider` imports the **CssBaseline** components which allows us to set a body background and also resets some initial browser styling values. One thing it's resetting is the css **box-sizing** property. If you experience misaligning in (canvas) components, this might be the property you want to check out.
85
462
 
86
- To test the package in another project without publishing it, you can follow these steps:
87
- In geoweb-theme:
463
+ ## Roadmap
88
464
 
89
- 1. `npm run package`
465
+ Theming will be never be finished as it is an ongoing progress. The goal is to have the `gwTheme` removed, and only use `lightTheme` and `darkTheme` throughout all libs and apps. The following points need to be done to reach that:
466
+
467
+ Other libs where `ThemeProvider` from `theme` should be used and `gwTheme` should be replaced:
468
+
469
+ - [ ] airmet/sigmet (**TICKET TO BE CREATED**)
470
+ - [ ] spaceweather (**TICKET TO BE CREATED**)
471
+ - [ ] taf (**TICKET TO BE CREATED**)
472
+ - [ ] form-fields (**TICKET TO BE CREATED**)
473
+ - [ ] shared (**TICKET TO BE CREATED**)
474
+
475
+ Another point of the roadmap is upgrade to MUI5. This is complete when all `@material-ui` references have been removed from the code
476
+
477
+ - [ ] Investigate impact of upgrade to MUI5 https://gitlab.com/opengeoweb/opengeoweb/-/issues/1355
478
+
479
+ ## Unit testing
480
+
481
+ ```
482
+ nx test theme
483
+ ```
90
484
 
91
- In yourproject:
485
+ ## Image snapshot testing
92
486
 
93
- 1. `cd <path/to/yourproject>`
94
- 2. `npm install <absolute path/to/tar/created/by/npm pack>`
487
+ The current regex filters on storykind `snapshots/`. So that means all stories inside the snapshots folder in storybook will be included. To add a new snapshot test, add a story inside the folder `libs/theme/src/lib/stories/snapshots`, and make sure in storybook itself it's also shown under snapshots.
95
488
 
96
- #### Bundling, packaging and publishing to NPM
489
+ [Read more about snapshot testing](https://gitlab.com/opengeoweb/opengeoweb/#image-snapshot-testing)
97
490
 
98
- We use Semantic Versioning, see the [documentation](https://semver.org) for details.
491
+ ### Running snapshot tests and updating snapshots locally
99
492
 
100
- 1. Decide how to bump the version, is it a major, minor or patch version?
101
- 2. Create a new branch based off master and ensure there is an upstream branch BEFORE going to the next step
102
- 3. Update the version by running `npm version major|minor|patch` on the new branch
103
- 4. Merge the branch into master
104
- 5. Go to the gitlab pipeline of master and run the publish stage
105
- 6. Check for the new version on [npm](https://www.npmjs.com/package/@opengeoweb/theme) and [gitlab](https://gitlab.com/opengeoweb/geoweb-theme/-/tags)
493
+ 1. You need to have [docker](https://docs.docker.com/get-docker/) installed and running.
494
+ 2. Start Chromium by running: `npm run start-chromium`. (This will start a docker container with chromium, to run snapshot tests in. We need this to make sure everyone gets the same snapshot results.)
495
+ 3. Run the snapshot tests: `npm run test:image-snap-theme`. This will first create a new static storybook build and then run the tests.
496
+ 4. If a snapshot test fails, you can find and inspect the differences in `libs/theme/src/lib/storyshots/__image_snapshots__/__diff_output__/`.
497
+ 5. To update the snapshots, run `npm run test:image-snap-theme-update`. Snapshots are saved under `libs/theme/src/lib/storyshots/__image_snapshots__/`. Make sure to commit the new snapshots.
498
+ 6. Stop Chromium by running: `npm run stop-chromium`.
106
499
 
107
- ### License
500
+ ## Questions and feedback
108
501
 
109
- This project is licensed under the terms of the [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) license.
502
+ Everything written here and coded is open for feedback. If you have any code related questions, please contact the GeoWeb team, if you have any questions about the design, naming and or guidelines please contact the designer [Didier](https://gitlab.com/didier.dezanet)
110
503
 
111
- Every file in this project has an header that specifies the licence and copyright. It is possible to add/remove the licence header using the following commands:
504
+ ## Documentation
112
505
 
113
- - `npm run licence:add` => it adds to all possible files the licence header if the file has not an header with the same content of the LICENCE file. This action can require a manual check in the case in which the file contains a wrong header (i.g. a simple word is missed), because it just adds another header without removing the wrong one.
506
+ https://opengeoweb.gitlab.io/opengeoweb/docs/theme/
114
507
 
115
- - `npm run licence:remove` => it removes the specific header from all files that contain an header with the same content of the LICENCE file. This action can require a manual check in the case in which the file contains a wrong header (i.g. a simple word is missed), because it just removes the correct header and not the wrong one.
508
+ > Written with [StackEdit](https://stackedit.io/).
package/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { GWTheme } from './theme';
1
+ export * from './lib/components/Theme';
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+ import { Theme as MUITheme } from '@material-ui/core';
3
+ interface ThemeContextProps {
4
+ toggleTheme?: () => void;
5
+ isDark?: boolean;
6
+ }
7
+ export declare const ThemeContext: React.Context<Partial<ThemeContextProps>>;
8
+ interface ThemeProviderProps {
9
+ children: React.ReactNode;
10
+ theme?: MUITheme;
11
+ disableCssBaseline?: boolean;
12
+ }
13
+ export declare const ThemeProvider: React.FC<ThemeProviderProps>;
14
+ export declare const useThemeContext: () => Partial<ThemeContextProps>;
15
+ export declare const ThemeWrapper: React.FC<ThemeProviderProps>;
16
+ export declare const ThemeWrapperOldTheme: React.FC<ThemeProviderProps>;
17
+ export {};
@@ -1 +1 @@
1
- export {};
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { GeowebColorPalette } from './types';
2
+ export declare const colors: GeowebColorPalette;
3
+ export declare const darkTheme: import("@material-ui/core").Theme;
@@ -1,7 +1,7 @@
1
- import { AlertClassKey } from '@material-ui/lab/Alert';
2
- declare module '@material-ui/core/styles/overrides' {
3
- interface ComponentNameToClassKey {
4
- MuiAlert: AlertClassKey;
5
- }
6
- }
7
- export declare const GWTheme: import("@material-ui/core").Theme;
1
+ import { AlertClassKey } from '@material-ui/lab/Alert';
2
+ declare module '@material-ui/core/styles/overrides' {
3
+ interface ComponentNameToClassKey {
4
+ MuiAlert: AlertClassKey;
5
+ }
6
+ }
7
+ export declare const GWTheme: import("@material-ui/core").Theme;
@@ -0,0 +1,5 @@
1
+ export { GWTheme } from './gwTheme';
2
+ export * from './ThemeContext';
3
+ export { lightTheme } from './lightTheme';
4
+ export { darkTheme } from './darkTheme';
5
+ export * from './types';
@@ -0,0 +1,3 @@
1
+ import { GeowebColorPalette } from './types';
2
+ export declare const colors: GeowebColorPalette;
3
+ export declare const lightTheme: import("@material-ui/core").Theme;