@scrabble-solver/scrabble-solver 2.8.2 → 2.8.4

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 (99) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +10 -10
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/eslint/.cache_8dgz12 +1 -1
  5. package/.next/cache/next-server.js.nft.json +1 -1
  6. package/.next/cache/webpack/client-production/0.pack +0 -0
  7. package/.next/cache/webpack/client-production/index.pack +0 -0
  8. package/.next/cache/webpack/server-production/0.pack +0 -0
  9. package/.next/cache/webpack/server-production/index.pack +0 -0
  10. package/.next/next-server.js.nft.json +1 -1
  11. package/.next/prerender-manifest.json +1 -1
  12. package/.next/routes-manifest.json +1 -1
  13. package/.next/server/chunks/206.js +98 -97
  14. package/.next/server/chunks/413.js +396 -677
  15. package/.next/server/chunks/515.js +546 -550
  16. package/.next/server/chunks/907.js +399 -681
  17. package/.next/server/middleware-build-manifest.js +1 -1
  18. package/.next/server/pages/404.html +5 -1
  19. package/.next/server/pages/404.js.nft.json +1 -1
  20. package/.next/server/pages/500.html +2 -2
  21. package/.next/server/pages/_app.js +7 -10
  22. package/.next/server/pages/_app.js.nft.json +1 -1
  23. package/.next/server/pages/_document.js +0 -3
  24. package/.next/server/pages/_error.js.nft.json +1 -1
  25. package/.next/server/pages/api/dictionary/[locale]/[word].js +114 -171
  26. package/.next/server/pages/api/solve.js +426 -1206
  27. package/.next/server/pages/index.html +17 -1
  28. package/.next/server/pages/index.js +7 -14
  29. package/.next/server/pages/index.js.nft.json +1 -1
  30. package/.next/server/pages/index.json +1 -1
  31. package/.next/static/-UOLkxdxU0PlKbXa09-xO/_buildManifest.js +1 -0
  32. package/.next/static/{nXSSCVI5pGlS_NxEidxkS → -UOLkxdxU0PlKbXa09-xO}/_ssgManifest.js +0 -0
  33. package/.next/static/chunks/56-2d34867599a0ac66.js +1 -0
  34. package/.next/static/chunks/pages/{404-02d949d2fe59e960.js → 404-30c06e61d256c5b2.js} +1 -1
  35. package/.next/static/chunks/pages/_app-6ffa2ab900772b67.js +1 -0
  36. package/.next/static/chunks/pages/{index-75517525489ab316.js → index-13ea7770a65c69ee.js} +1 -1
  37. package/.next/static/css/{d676d43c6b9c9a57.css → 551d09cac435debb.css} +1 -1
  38. package/.next/static/css/{6a9e5ba3f77c27f2.css → cdbc9e0afcff5473.css} +1 -1
  39. package/.next/trace +42 -42
  40. package/package.json +14 -14
  41. package/src/components/Board/Board.tsx +1 -1
  42. package/src/components/Board/BoardPure.tsx +1 -1
  43. package/src/components/Board/components/Cell/Button.tsx +1 -1
  44. package/src/components/Board/components/Cell/Cell.tsx +1 -1
  45. package/src/components/Board/components/Cell/CellPure.tsx +1 -1
  46. package/src/components/Board/hooks/useGrid.ts +9 -0
  47. package/src/components/Button/Button.tsx +1 -1
  48. package/src/components/Checkbox/Checkbox.tsx +1 -1
  49. package/src/components/Dictionary/Dictionary.tsx +1 -1
  50. package/src/components/DictionaryInput/DictionaryInput.tsx +1 -1
  51. package/src/components/EmptyState/EmptyState.tsx +1 -1
  52. package/src/components/Key/Key.tsx +1 -1
  53. package/src/components/KeyMap/KeyMap.tsx +2 -2
  54. package/src/components/KeyMap/components/Mapping/Mapping.module.scss +4 -0
  55. package/src/components/KeyMap/components/Mapping/Mapping.tsx +16 -12
  56. package/src/components/Loading/Loading.tsx +1 -1
  57. package/src/components/Logo/Logo.tsx +1 -1
  58. package/src/components/NavButtons/NavButtons.tsx +1 -1
  59. package/src/components/NotFound/NotFound.tsx +1 -1
  60. package/src/components/PlainTiles/PlainTiles.tsx +5 -1
  61. package/src/components/PlainTiles/Tile.tsx +1 -1
  62. package/src/components/Rack/Rack.tsx +1 -1
  63. package/src/components/Rack/RackTile.tsx +1 -1
  64. package/src/components/Radio/Radio.tsx +1 -1
  65. package/src/components/RemainingTiles/Character.tsx +1 -1
  66. package/src/components/RemainingTiles/RemainingTiles.tsx +1 -1
  67. package/src/components/Results/Cell.tsx +1 -1
  68. package/src/components/Results/HeaderButton.tsx +1 -1
  69. package/src/components/Results/Result.tsx +1 -1
  70. package/src/components/Results/Results.tsx +1 -1
  71. package/src/components/Results/SolveButton.tsx +1 -1
  72. package/src/components/ResultsInput/ResultsInput.tsx +1 -1
  73. package/src/components/Screen/Screen.tsx +1 -1
  74. package/src/components/Settings/Settings.tsx +1 -1
  75. package/src/components/Settings/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +1 -1
  76. package/src/components/Settings/components/ConfigSetting/ConfigSetting.tsx +1 -1
  77. package/src/components/Settings/components/LocaleSetting/LocaleSetting.tsx +1 -1
  78. package/src/components/Sidebar/Sidebar.tsx +1 -1
  79. package/src/components/Sidebar/components/Section/Section.tsx +1 -1
  80. package/src/components/Splash/Splash.tsx +1 -1
  81. package/src/components/SquareButton/Link.tsx +1 -1
  82. package/src/components/SquareButton/SquareButton.tsx +1 -1
  83. package/src/components/SvgFontCss/SvgFontCss.tsx +12 -0
  84. package/src/components/SvgFontCss/index.ts +1 -0
  85. package/src/components/Tile/Tile.tsx +1 -1
  86. package/src/components/Tile/TilePure.tsx +2 -2
  87. package/src/components/Tooltip/useTooltip.tsx +1 -1
  88. package/src/components/Well/Well.tsx +1 -1
  89. package/src/components/index.ts +1 -0
  90. package/src/hooks/usePortal.tsx +19 -9
  91. package/src/lib/createKeyboardNavigation.ts +3 -0
  92. package/src/lib/memoize.ts +1 -1
  93. package/src/pages/_app.tsx +1 -1
  94. package/src/pages/_document.tsx +1 -1
  95. package/src/pages/index.tsx +6 -15
  96. package/src/styles/global.scss +3 -0
  97. package/.next/static/chunks/195-fcadef5c6eed8338.js +0 -1
  98. package/.next/static/chunks/pages/_app-f4030148d742bcd2.js +0 -1
  99. package/.next/static/nXSSCVI5pGlS_NxEidxkS/_buildManifest.js +0 -1
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@scrabble-solver/scrabble-solver",
3
- "version": "2.8.2",
3
+ "version": "2.8.4",
4
4
  "description": "Scrabble Solver 2 - App",
5
5
  "engines": {
6
- "node": ">=16.0.0"
6
+ "node": ">=16"
7
7
  },
8
8
  "repository": {
9
9
  "type": "git",
@@ -30,13 +30,13 @@
30
30
  "dependencies": {
31
31
  "@popperjs/core": "^2.11.6",
32
32
  "@reduxjs/toolkit": "^1.8.5",
33
- "@scrabble-solver/configs": "^2.8.2",
34
- "@scrabble-solver/constants": "^2.8.2",
35
- "@scrabble-solver/dictionaries": "^2.8.2",
36
- "@scrabble-solver/logger": "^2.8.2",
37
- "@scrabble-solver/solver": "^2.8.2",
38
- "@scrabble-solver/types": "^2.8.2",
39
- "@scrabble-solver/word-definitions": "^2.8.2",
33
+ "@scrabble-solver/configs": "^2.8.4",
34
+ "@scrabble-solver/constants": "^2.8.4",
35
+ "@scrabble-solver/dictionaries": "^2.8.4",
36
+ "@scrabble-solver/logger": "^2.8.4",
37
+ "@scrabble-solver/solver": "^2.8.4",
38
+ "@scrabble-solver/types": "^2.8.4",
39
+ "@scrabble-solver/word-definitions": "^2.8.4",
40
40
  "classnames": "^2.3.2",
41
41
  "next": "^12.3.1",
42
42
  "normalize.css": "^8.0.1",
@@ -45,7 +45,7 @@
45
45
  "react-modal": "^3.15.1",
46
46
  "react-popper": "^2.3.0",
47
47
  "react-portal": "^4.2.2",
48
- "react-redux": "^8.0.2",
48
+ "react-redux": "^8.0.4",
49
49
  "react-use": "^17.4.0",
50
50
  "react-window": "^1.8.7",
51
51
  "redux": "^4.2.0",
@@ -54,9 +54,9 @@
54
54
  "uuid": "^9.0.0"
55
55
  },
56
56
  "devDependencies": {
57
- "@svgr/webpack": "^6.3.1",
57
+ "@svgr/webpack": "^6.4.0",
58
58
  "@types/classnames": "^2.3.0",
59
- "@types/react": "^18.0.20",
59
+ "@types/react": "^18.0.21",
60
60
  "@types/react-dom": "^18.0.6",
61
61
  "@types/react-modal": "^3.13.1",
62
62
  "@types/react-portal": "^4.0.4",
@@ -66,7 +66,7 @@
66
66
  "@types/redux-saga": "^0.10.5",
67
67
  "@types/uuid": "^8.3.4",
68
68
  "env-cmd": "^10.1.0",
69
- "sass": "^1.54.9"
69
+ "sass": "^1.55.0"
70
70
  },
71
- "gitHead": "bf360562a79572dd4640ac7cd7f26199f1ba6899"
71
+ "gitHead": "3b0c4c9d7987e456f34f7e2918931b0024b8a393"
72
72
  }
@@ -1,4 +1,4 @@
1
- import React, { FunctionComponent, Ref } from 'react';
1
+ import { FunctionComponent, Ref } from 'react';
2
2
 
3
3
  import { selectRowsWithCandidate, useTypedSelector } from 'state';
4
4
 
@@ -1,6 +1,6 @@
1
1
  import { Cell } from '@scrabble-solver/types';
2
2
  import classNames from 'classnames';
3
- import React, { FunctionComponent, KeyboardEventHandler, memo, Ref, RefObject } from 'react';
3
+ import { FunctionComponent, KeyboardEventHandler, memo, Ref, RefObject } from 'react';
4
4
 
5
5
  import styles from './Board.module.scss';
6
6
  import { Cell as CellComponent } from './components';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { ButtonHTMLAttributes, FunctionComponent, MouseEventHandler, ReactNode } from 'react';
2
+ import { ButtonHTMLAttributes, FunctionComponent, MouseEventHandler, ReactNode } from 'react';
3
3
 
4
4
  import { useTooltip } from '../../../Tooltip';
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { EMPTY_CELL } from '@scrabble-solver/constants';
2
2
  import { Cell as CellModel } from '@scrabble-solver/types';
3
- import React, { FunctionComponent, RefObject, useCallback, useMemo } from 'react';
3
+ import { FunctionComponent, RefObject, useCallback, useMemo } from 'react';
4
4
  import { useDispatch } from 'react-redux';
5
5
 
6
6
  import { getTileSizes } from 'lib';
@@ -1,6 +1,6 @@
1
1
  import { Bonus, Cell, Tile as TileModel } from '@scrabble-solver/types';
2
2
  import classNames from 'classnames';
3
- import React, { CSSProperties, FocusEventHandler, FunctionComponent, memo, MouseEventHandler, RefObject } from 'react';
3
+ import { CSSProperties, FocusEventHandler, FunctionComponent, memo, MouseEventHandler, RefObject } from 'react';
4
4
 
5
5
  import { ArrowDown } from 'icons';
6
6
  import { Translate } from 'types';
@@ -214,6 +214,15 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
214
214
  dispatch(boardSlice.actions.changeCellValue({ ...position, value: character }));
215
215
  onMoveFocus('forward');
216
216
  },
217
+ onSpace: (event) => {
218
+ const position = getInputRefPosition(event.target as HTMLInputElement);
219
+
220
+ if (!position) {
221
+ return;
222
+ }
223
+
224
+ dispatch(boardSlice.actions.toggleCellIsBlank(position));
225
+ },
217
226
  });
218
227
  }, [changeActiveIndex, config, dispatch, lastDirectionRef, onDirectionToggle, rows]);
219
228
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { ButtonHTMLAttributes, FunctionComponent, MouseEventHandler, ReactNode, SVGAttributes } from 'react';
2
+ import { ButtonHTMLAttributes, FunctionComponent, MouseEventHandler, ReactNode, SVGAttributes } from 'react';
3
3
 
4
4
  import { useTooltip } from '../Tooltip';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { ChangeEventHandler, FunctionComponent, ReactNode } from 'react';
2
+ import { ChangeEventHandler, FunctionComponent, ReactNode } from 'react';
3
3
 
4
4
  import { CheckboxChecked, CheckboxEmpty } from 'icons';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent } from 'react';
2
+ import { FunctionComponent } from 'react';
3
3
 
4
4
  import { selectDictionary, useTranslate, useTypedSelector } from 'state';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { ChangeEvent, FormEvent, FunctionComponent } from 'react';
2
+ import { ChangeEvent, FormEvent, FunctionComponent } from 'react';
3
3
  import { useDispatch } from 'react-redux';
4
4
 
5
5
  import { dictionarySlice, selectDictionary, useTranslate, useTypedSelector } from 'state';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent, ReactNode, useMemo } from 'react';
2
+ import { FunctionComponent, ReactNode, useMemo } from 'react';
3
3
 
4
4
  import { COLOR_BLUE, COLOR_GREEN, COLOR_RED, COLOR_YELLOW } from 'parameters';
5
5
  import { useTranslate } from 'state';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent, ReactNode } from 'react';
2
+ import { FunctionComponent, ReactNode } from 'react';
3
3
 
4
4
  import styles from './Key.module.scss';
5
5
 
@@ -1,4 +1,4 @@
1
- import React, { FunctionComponent } from 'react';
1
+ import { FunctionComponent } from 'react';
2
2
 
3
3
  import { selectConfig, useTranslate, useTypedSelector } from 'state';
4
4
 
@@ -42,7 +42,7 @@ const KeyMap: FunctionComponent<Props> = ({ className, isOpen, onClose }) => {
42
42
  </Sidebar.Section>
43
43
 
44
44
  <Sidebar.Section title={translate('keyMap.board')}>
45
- <Mapping description={translate('keyMap.board.toggle-blank')} mapping={[[CTRL, <Key key="b">B</Key>]]} />
45
+ <Mapping description={translate('keyMap.board.toggle-blank')} mapping={[SPACE, [CTRL, <Key key="b">B</Key>]]} />
46
46
  <Mapping description={translate('keyMap.board.toggle-direction')} mapping={[[CTRL, ARROWS]]} />
47
47
  </Sidebar.Section>
48
48
 
@@ -24,6 +24,10 @@
24
24
  margin: 0 var(--spacing--s);
25
25
  }
26
26
 
27
+ .slash {
28
+ margin: 0 var(--spacing--m);
29
+ }
30
+
27
31
  .group {
28
32
  &:first-child {
29
33
  margin-left: 0;
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent, ReactNode } from 'react';
2
+ import { Fragment, FunctionComponent, ReactNode } from 'react';
3
3
 
4
4
  import styles from './Mapping.module.scss';
5
5
 
@@ -15,17 +15,21 @@ const Mapping: FunctionComponent<Props> = ({ className, description, mapping })
15
15
 
16
16
  <div className={styles.keys}>
17
17
  {mapping.map((key, index) => (
18
- <div className={styles.group} key={index}>
19
- {Array.isArray(key) ? (
20
- <>
21
- {key[0]}
22
- <span className={styles.plus}>+</span>
23
- {key[1]}
24
- </>
25
- ) : (
26
- key
27
- )}
28
- </div>
18
+ <Fragment key={index}>
19
+ <div className={styles.group}>
20
+ {Array.isArray(key) ? (
21
+ <>
22
+ {key[0]}
23
+ <span className={styles.plus}>+</span>
24
+ {key[1]}
25
+ </>
26
+ ) : (
27
+ key
28
+ )}
29
+ </div>
30
+
31
+ {mapping.length > 1 && index < mapping.length - 1 && <span className={styles.slash}>/</span>}
32
+ </Fragment>
29
33
  ))}
30
34
  </div>
31
35
  </div>
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent, useMemo } from 'react';
2
+ import { FunctionComponent, useMemo } from 'react';
3
3
 
4
4
  import { useTranslate } from 'state';
5
5
 
@@ -1,4 +1,4 @@
1
- import React, { CSSProperties, FunctionComponent } from 'react';
1
+ import { CSSProperties, FunctionComponent } from 'react';
2
2
 
3
3
  import PlainTiles from '../PlainTiles';
4
4
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent } from 'react';
2
+ import { FunctionComponent } from 'react';
3
3
 
4
4
  import { Cog, Eraser, Github, Keyboard, Sack } from 'icons';
5
5
  import { GITHUB_PROJECT_URL } from 'parameters';
@@ -1,5 +1,5 @@
1
1
  import Link from 'next/link';
2
- import React, { FunctionComponent } from 'react';
2
+ import { FunctionComponent } from 'react';
3
3
 
4
4
  import { DashCircleFill } from 'icons';
5
5
 
@@ -1,5 +1,7 @@
1
1
  import classNames from 'classnames';
2
- import React, { CSSProperties, FunctionComponent, useMemo } from 'react';
2
+ import { CSSProperties, FunctionComponent, useMemo } from 'react';
3
+
4
+ import SvgFontCss from '../SvgFontCss';
3
5
 
4
6
  import { createPlainTiles, getViewbox } from './lib';
5
7
  import styles from './PlainTiles.module.scss';
@@ -28,6 +30,8 @@ const PlainTiles: FunctionComponent<Props> = ({ className, color, content, dropS
28
30
  viewBox={getViewbox(content)}
29
31
  xmlns="http://www.w3.org/2000/svg"
30
32
  >
33
+ <SvgFontCss />
34
+
31
35
  {tiles.map((tile, index) => (
32
36
  <Tile
33
37
  character={tile.character}
@@ -1,4 +1,4 @@
1
- import React, { FunctionComponent } from 'react';
1
+ import { FunctionComponent } from 'react';
2
2
 
3
3
  interface Props {
4
4
  character: string;
@@ -1,6 +1,6 @@
1
1
  import { BLANK } from '@scrabble-solver/constants';
2
2
  import classNames from 'classnames';
3
- import React, { createRef, FunctionComponent, useCallback, useMemo, useRef } from 'react';
3
+ import { createRef, FunctionComponent, useCallback, useMemo, useRef } from 'react';
4
4
 
5
5
  import { createArray, createKeyboardNavigation, zipCharactersAndTiles } from 'lib';
6
6
  import { selectConfig, selectRack, selectResultCandidateTiles, useTypedSelector } from 'state';
@@ -1,6 +1,6 @@
1
1
  import { BLANK } from '@scrabble-solver/constants';
2
2
  import { Tile as TileModel } from '@scrabble-solver/types';
3
- import React, {
3
+ import {
4
4
  FunctionComponent,
5
5
  KeyboardEventHandler,
6
6
  MutableRefObject,
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { ChangeEventHandler, FunctionComponent, ReactNode } from 'react';
2
+ import { ChangeEventHandler, FunctionComponent, ReactNode } from 'react';
3
3
 
4
4
  import styles from './Radio.module.scss';
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { BLANK } from '@scrabble-solver/constants';
2
2
  import classNames from 'classnames';
3
- import React, { FunctionComponent } from 'react';
3
+ import { FunctionComponent } from 'react';
4
4
 
5
5
  import { REMAINING_TILES_TILE_SIZE } from 'parameters';
6
6
  import { selectCharacterPoints, useTypedSelector } from 'state';
@@ -1,4 +1,4 @@
1
- import React, { FunctionComponent } from 'react';
1
+ import { FunctionComponent } from 'react';
2
2
 
3
3
  import { selectRemainingTilesGroups, useTranslate, useTypedSelector } from 'state';
4
4
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent } from 'react';
2
+ import { FunctionComponent } from 'react';
3
3
 
4
4
  import { useTranslate } from 'state';
5
5
  import { TranslationKey } from 'types';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { ReactElement } from 'react';
2
+ import { ReactElement } from 'react';
3
3
  import { useDispatch } from 'react-redux';
4
4
 
5
5
  import { SortDown, SortUp } from 'icons';
@@ -1,4 +1,4 @@
1
- import React, { CSSProperties, ReactElement } from 'react';
1
+ import { CSSProperties, ReactElement } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
3
 
4
4
  import { resultsSlice, selectSortedFilteredResults, useTypedSelector } from 'state';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent } from 'react';
2
+ import { FunctionComponent } from 'react';
3
3
  import { FixedSizeList } from 'react-window';
4
4
 
5
5
  import { RESULTS_HEADER_HEIGHT, RESULTS_INPUT_HEIGHT, RESULTS_ITEM_HEIGHT } from 'parameters';
@@ -1,4 +1,4 @@
1
- import React, { FunctionComponent } from 'react';
1
+ import { FunctionComponent } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
3
 
4
4
  import { Play } from 'icons';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { ChangeEvent, FunctionComponent } from 'react';
2
+ import { ChangeEvent, FunctionComponent } from 'react';
3
3
  import { useDispatch } from 'react-redux';
4
4
 
5
5
  import { resultsSlice, selectResultsQuery, useTranslate, useTypedSelector } from 'state';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { AnimationEventHandler, FunctionComponent, ReactNode } from 'react';
2
+ import { AnimationEventHandler, FunctionComponent, ReactNode } from 'react';
3
3
 
4
4
  import styles from './Screen.module.scss';
5
5
 
@@ -1,4 +1,4 @@
1
- import React, { FunctionComponent } from 'react';
1
+ import { FunctionComponent } from 'react';
2
2
 
3
3
  import { useTranslate } from 'state';
4
4
 
@@ -1,4 +1,4 @@
1
- import React, { ChangeEvent, FunctionComponent } from 'react';
1
+ import { ChangeEvent, FunctionComponent } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
3
 
4
4
  import { selectAutoGroupTiles, settingsSlice, useTranslate, useTypedSelector } from 'state';
@@ -1,4 +1,4 @@
1
- import React, { ChangeEvent, FunctionComponent } from 'react';
1
+ import { ChangeEvent, FunctionComponent } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
3
 
4
4
  import { selectConfigId, settingsSlice, useTypedSelector } from 'state';
@@ -1,6 +1,6 @@
1
1
  import { Locale } from '@scrabble-solver/types';
2
2
  import classNames from 'classnames';
3
- import React, { ChangeEvent, FunctionComponent } from 'react';
3
+ import { ChangeEvent, FunctionComponent } from 'react';
4
4
  import { useDispatch } from 'react-redux';
5
5
 
6
6
  import { selectLocale, settingsSlice, useTypedSelector } from 'state';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent, ReactNode } from 'react';
2
+ import { FunctionComponent, ReactNode } from 'react';
3
3
  import Modal from 'react-modal';
4
4
 
5
5
  import { Cross } from 'icons';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { FunctionComponent, ReactNode } from 'react';
2
+ import { FunctionComponent, ReactNode } from 'react';
3
3
 
4
4
  import styles from './Section.module.scss';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { AnimationEventHandler, FunctionComponent } from 'react';
2
+ import { AnimationEventHandler, FunctionComponent } from 'react';
3
3
 
4
4
  import Logo from '../Logo';
5
5
  import Screen from '../Screen';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { AnchorHTMLAttributes, FunctionComponent, SVGAttributes } from 'react';
2
+ import { AnchorHTMLAttributes, FunctionComponent, SVGAttributes } from 'react';
3
3
 
4
4
  import { useTooltip } from '../Tooltip';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { ButtonHTMLAttributes, FunctionComponent, MouseEventHandler, SVGAttributes } from 'react';
2
+ import { ButtonHTMLAttributes, FunctionComponent, MouseEventHandler, SVGAttributes } from 'react';
3
3
 
4
4
  import { useTooltip } from '../Tooltip';
5
5
 
@@ -0,0 +1,12 @@
1
+ import { FunctionComponent } from 'react';
2
+
3
+ // eslint-disable-next-line max-len
4
+ const CSS = `@import url('https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&family=Open+Sans:wght@400;700&family=Roboto+Mono&display=swap');
5
+
6
+ text {
7
+ font-family: 'Open Sans';
8
+ }`;
9
+
10
+ const SvgFontCss: FunctionComponent = () => <style type="text/css">{CSS}</style>;
11
+
12
+ export default SvgFontCss;
@@ -0,0 +1 @@
1
+ export { default } from './SvgFontCss';
@@ -1,5 +1,5 @@
1
1
  import { EMPTY_CELL } from '@scrabble-solver/constants';
2
- import React, {
2
+ import {
3
3
  createRef,
4
4
  FocusEventHandler,
5
5
  FunctionComponent,
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, {
2
+ import {
3
3
  ChangeEventHandler,
4
4
  CSSProperties,
5
5
  FocusEventHandler,
@@ -66,7 +66,7 @@ const TilePure: FunctionComponent<Props> = ({
66
66
  style={style}
67
67
  >
68
68
  <input
69
- autoCapitalize="off"
69
+ autoCapitalize="none"
70
70
  autoComplete="off"
71
71
  autoCorrect="off"
72
72
  autoFocus={autoFocus}
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, {
2
+ import {
3
3
  FocusEvent,
4
4
  FocusEventHandler,
5
5
  MouseEvent,
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import React, { forwardRef, HTMLAttributes, ReactNode } from 'react';
2
+ import { forwardRef, HTMLAttributes, ReactNode } from 'react';
3
3
 
4
4
  import styles from './Well.module.scss';
5
5
 
@@ -21,6 +21,7 @@ export { default as Settings } from './Settings';
21
21
  export { default as Sidebar } from './Sidebar';
22
22
  export { default as Splash } from './Splash';
23
23
  export { default as SquareButton } from './SquareButton';
24
+ export { default as SvgFontCss } from './SvgFontCss';
24
25
  export { default as Tile } from './Tile';
25
26
  export { useTooltip } from './Tooltip';
26
27
  export { default as Well } from './Well';
@@ -1,5 +1,5 @@
1
- import React, { ReactNode, useLayoutEffect, useMemo } from 'react';
2
- import { render, unmountComponentAtNode } from 'react-dom';
1
+ import { ReactNode, useLayoutEffect, useRef } from 'react';
2
+ import { createRoot, Root } from 'react-dom/client';
3
3
  import { Portal } from 'react-portal';
4
4
 
5
5
  import { canUseDom, noop } from 'lib';
@@ -12,26 +12,36 @@ interface Props {
12
12
  type TagName = Parameters<typeof document.createElement>[0];
13
13
 
14
14
  const usePortal = (children: ReactNode, { disabled = false, tagName = 'div' }: Props = {}): void => {
15
- const element = useMemo(() => document.createElement(tagName), [tagName]);
15
+ const rootRef = useRef<Root | null>(null);
16
16
 
17
17
  useLayoutEffect(() => {
18
18
  if (disabled) {
19
19
  return noop;
20
20
  }
21
21
 
22
+ const element = document.createElement(tagName);
22
23
  document.body.appendChild(element);
24
+ const root = createRoot(element);
25
+ rootRef.current = root;
23
26
 
24
27
  return () => {
25
- unmountComponentAtNode(element);
26
- document.body.removeChild(element);
28
+ // We need setTimeout for async unmount, otherwise we get this warning:
29
+ // "Attempted to synchronously unmount a root while React was already
30
+ // rendering. React cannot finish unmounting the root until the current
31
+ // render has completed, which may lead to a race condition.""
32
+ setTimeout(() => {
33
+ rootRef.current = null;
34
+ root.unmount();
35
+ element.remove();
36
+ }, 0);
27
37
  };
28
- }, [disabled, element]);
38
+ }, [disabled, tagName]);
29
39
 
30
40
  useLayoutEffect(() => {
31
- if (!disabled) {
32
- render(<Portal>{children}</Portal>, element);
41
+ if (rootRef.current) {
42
+ rootRef.current.render(<Portal>{children}</Portal>);
33
43
  }
34
- }, [children, disabled, element]);
44
+ }, [children, disabled, rootRef]);
35
45
  };
36
46
 
37
47
  export default canUseDom ? usePortal : noop;
@@ -11,6 +11,7 @@ interface Parameters {
11
11
  onDelete?: KeyboardEventHandler<HTMLInputElement>;
12
12
  onEnter?: KeyboardEventHandler<HTMLInputElement>;
13
13
  onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
14
+ onSpace?: KeyboardEventHandler<HTMLInputElement>;
14
15
  }
15
16
 
16
17
  const createKeyboardNavigation = ({
@@ -22,6 +23,7 @@ const createKeyboardNavigation = ({
22
23
  onDelete = noop,
23
24
  onEnter = noop,
24
25
  onKeyDown = noop,
26
+ onSpace = noop,
25
27
  }: Parameters): KeyboardEventHandler<HTMLInputElement> => {
26
28
  const handlers: Record<string, KeyboardEventHandler<HTMLInputElement>> = {
27
29
  ArrowUp: onArrowUp,
@@ -31,6 +33,7 @@ const createKeyboardNavigation = ({
31
33
  Backspace: onBackspace,
32
34
  Delete: onDelete,
33
35
  Enter: onEnter,
36
+ ' ': onSpace,
34
37
  };
35
38
 
36
39
  const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {
@@ -1,5 +1,5 @@
1
1
  interface AnyFunction {
2
- (...parameters: any): any; // eslint-disable-line @typescript-eslint/no-explicit-any
2
+ (...parameters: any[]): any; // eslint-disable-line @typescript-eslint/no-explicit-any
3
3
  }
4
4
 
5
5
  interface AnyCachedFunction<T extends AnyFunction> extends AnyFunction {
@@ -1,6 +1,6 @@
1
1
  import { AppProps } from 'next/app';
2
2
  import Head from 'next/head';
3
- import React, { FunctionComponent } from 'react';
3
+ import { FunctionComponent } from 'react';
4
4
  import { Provider } from 'react-redux';
5
5
 
6
6
  import { createAppStore } from 'state';