@scrabble-solver/scrabble-solver 2.10.2 → 2.10.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 (215) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +31 -19
  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/edge-server-production/0.pack +0 -0
  9. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  10. package/.next/cache/webpack/server-production/0.pack +0 -0
  11. package/.next/cache/webpack/server-production/index.pack +0 -0
  12. package/.next/next-server.js.nft.json +1 -1
  13. package/.next/prerender-manifest.json +1 -1
  14. package/.next/routes-manifest.json +1 -1
  15. package/.next/server/chunks/176.js +1269 -1559
  16. package/.next/server/chunks/579.js +50 -26
  17. package/.next/server/middleware-build-manifest.js +1 -1
  18. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  19. package/.next/server/pages/404.html +2 -2
  20. package/.next/server/pages/404.js.nft.json +1 -1
  21. package/.next/server/pages/500.html +2 -2
  22. package/.next/server/pages/_app.js.nft.json +1 -1
  23. package/.next/server/pages/api/dictionary/[locale]/[word].js +2 -1
  24. package/.next/server/pages/api/solve.js +22 -6
  25. package/.next/server/pages/index.html +2 -2
  26. package/.next/server/pages/index.js +1539 -52
  27. package/.next/server/pages/index.js.nft.json +1 -1
  28. package/.next/server/pages/index.json +1 -1
  29. package/.next/server/pages-manifest.json +1 -1
  30. package/.next/static/P7XhuDLmwJJqC8kgPjX42/_buildManifest.js +1 -0
  31. package/.next/static/{FjrbXpI5fkt4lmko-vL_7 → P7XhuDLmwJJqC8kgPjX42}/_ssgManifest.js +0 -0
  32. package/.next/static/chunks/490-d29992f1c264d70e.js +5 -0
  33. package/.next/static/chunks/528-9942ddad0031ff79.js +1 -0
  34. package/.next/static/chunks/pages/{404-24f9617eeb8d6dc1.js → 404-6c99a0c91257c60b.js} +1 -1
  35. package/.next/static/chunks/pages/_app-fa0661b072fc6af9.js +24 -0
  36. package/.next/static/chunks/pages/index-d761f0af070273d2.js +1 -0
  37. package/.next/static/css/78e42ad01f580f64.css +1 -0
  38. package/.next/static/css/97eb6ee0c4300c83.css +1 -0
  39. package/.next/static/css/dcca0c1a39cf5ef5.css +1 -0
  40. package/.next/trace +55 -52
  41. package/package.json +11 -9
  42. package/src/components/Badge/Badge.module.scss +4 -5
  43. package/src/components/Board/BoardPure.tsx +5 -5
  44. package/src/components/Board/components/Cell/Cell.module.scss +15 -2
  45. package/src/components/Button/Button.module.scss +10 -38
  46. package/src/components/Button/Button.tsx +6 -5
  47. package/src/components/Dictionary/Dictionary.module.scss +1 -2
  48. package/src/components/Dictionary/Dictionary.tsx +2 -6
  49. package/src/components/DictionaryInput/DictionaryInput.module.scss +1 -3
  50. package/src/components/EmptyState/EmptyState.module.scss +6 -7
  51. package/src/components/EmptyState/EmptyState.tsx +6 -6
  52. package/src/components/Key/Key.module.scss +0 -1
  53. package/src/components/{Splash/Splash.module.scss → LogoSplashScreen/LogoSplashScreen.module.scss} +1 -1
  54. package/src/components/{Splash/Splash.tsx → LogoSplashScreen/LogoSplashScreen.tsx} +7 -7
  55. package/src/components/LogoSplashScreen/index.ts +1 -0
  56. package/src/components/{Sidebar/Sidebar.module.scss → Modal/Modal.module.scss} +25 -20
  57. package/src/components/{Sidebar/Sidebar.tsx → Modal/Modal.tsx} +9 -9
  58. package/src/components/{Sidebar → Modal}/components/Section/Section.module.scss +0 -0
  59. package/src/components/{Sidebar → Modal}/components/Section/Section.tsx +0 -0
  60. package/src/components/{Sidebar → Modal}/components/Section/index.ts +0 -0
  61. package/src/components/{Sidebar → Modal}/components/index.ts +0 -0
  62. package/src/components/Modal/index.ts +1 -0
  63. package/src/components/NavButtons/NavButtons.tsx +22 -3
  64. package/src/components/Progress/Progress.module.scss +9 -0
  65. package/src/components/Progress/Progress.tsx +38 -0
  66. package/src/components/Progress/index.ts +1 -0
  67. package/src/components/Rack/Rack.module.scss +2 -0
  68. package/src/components/Rack/Rack.tsx +3 -1
  69. package/src/components/Rack/RackTile.tsx +3 -2
  70. package/src/components/ResultCandidatePicker/ResultCandidatePicker.module.scss +76 -0
  71. package/src/components/ResultCandidatePicker/ResultCandidatePicker.tsx +38 -0
  72. package/src/components/ResultCandidatePicker/index.ts +1 -0
  73. package/src/components/Results/Result.tsx +64 -43
  74. package/src/components/Results/Results.module.scss +9 -16
  75. package/src/components/Results/Results.tsx +45 -28
  76. package/src/components/Results/SolveButton.tsx +9 -7
  77. package/src/components/Results/{getColumns.ts → getLocaleColumns.ts} +2 -2
  78. package/src/components/Results/types.ts +16 -0
  79. package/src/components/Results/useColumns.ts +44 -0
  80. package/src/components/ResultsInput/ResultsInput.module.scss +1 -3
  81. package/src/components/Sizer/Sizer.module.scss +10 -0
  82. package/src/components/Sizer/Sizer.tsx +10 -0
  83. package/src/components/Sizer/index.ts +1 -0
  84. package/src/components/Solver/Solver.module.scss +83 -27
  85. package/src/components/Solver/Solver.tsx +157 -24
  86. package/src/components/Solver/components/ApplyButton/ApplyButton.module.scss +5 -0
  87. package/src/components/Solver/components/ApplyButton/ApplyButton.tsx +37 -0
  88. package/src/components/Solver/components/ApplyButton/index.ts +1 -0
  89. package/src/components/Solver/components/EmptyState/EmptyState.module.scss +59 -0
  90. package/src/components/Solver/components/EmptyState/EmptyState.tsx +41 -0
  91. package/src/components/Solver/components/EmptyState/index.ts +1 -0
  92. package/src/components/Solver/components/SolveButton/SolveButton.module.scss +4 -0
  93. package/src/components/Solver/components/SolveButton/SolveButton.tsx +42 -0
  94. package/src/components/Solver/components/SolveButton/index.ts +1 -0
  95. package/src/components/Solver/components/index.ts +3 -0
  96. package/src/components/{Screen/Screen.module.scss → SplashScreen/SplashScreen.module.scss} +2 -12
  97. package/src/components/{Screen/Screen.tsx → SplashScreen/SplashScreen.tsx} +4 -4
  98. package/src/components/SplashScreen/index.ts +1 -0
  99. package/src/components/SquareButton/SquareButton.module.scss +3 -3
  100. package/src/components/Tile/Tile.module.scss +7 -15
  101. package/src/components/Tooltip/Tooltip.module.scss +0 -1
  102. package/src/components/index.ts +6 -7
  103. package/src/hooks/index.ts +1 -1
  104. package/src/hooks/useMediaQuery.ts +11 -0
  105. package/src/hooks/usePortal.tsx +1 -1
  106. package/src/i18n/de.json +2 -0
  107. package/src/i18n/en.json +2 -0
  108. package/src/i18n/es.json +2 -0
  109. package/src/i18n/fa.json +2 -0
  110. package/src/i18n/fr.json +2 -0
  111. package/src/i18n/pl.json +2 -0
  112. package/src/icons/CardChecklist.svg +5 -0
  113. package/src/icons/Check.svg +2 -2
  114. package/src/icons/ChevronDown.svg +4 -0
  115. package/src/icons/CrossCircleFill.svg +4 -0
  116. package/src/icons/{CrossFill.svg → CrossSquareFill.svg} +0 -0
  117. package/src/icons/ExclamationTriangleFill.svg +4 -0
  118. package/src/icons/InfoCircleFill.svg +4 -0
  119. package/src/icons/List.svg +4 -0
  120. package/src/icons/Search.svg +4 -0
  121. package/src/icons/index.ts +8 -2
  122. package/src/{components/KeyMap/KeyMap.tsx → modals/KeyMapModal/KeyMapModal.tsx} +11 -13
  123. package/src/{components/KeyMap → modals/KeyMapModal}/components/Mapping/Mapping.module.scss +0 -0
  124. package/src/{components/KeyMap → modals/KeyMapModal}/components/Mapping/Mapping.tsx +0 -0
  125. package/src/{components/KeyMap → modals/KeyMapModal}/components/Mapping/index.ts +0 -0
  126. package/src/{components/KeyMap → modals/KeyMapModal}/components/index.ts +0 -0
  127. package/src/modals/KeyMapModal/index.ts +1 -0
  128. package/src/{components/KeyMap → modals/KeyMapModal}/keys.tsx +1 -2
  129. package/src/modals/MenuModal/MenuModal.module.scss +46 -0
  130. package/src/modals/MenuModal/MenuModal.tsx +54 -0
  131. package/src/modals/MenuModal/index.ts +1 -0
  132. package/src/modals/RemainingTilesModal/RemainingTilesModal.module.scss +28 -0
  133. package/src/{components/RemainingTiles/RemainingTiles.tsx → modals/RemainingTilesModal/RemainingTilesModal.tsx} +14 -12
  134. package/src/{components/RemainingTiles → modals/RemainingTilesModal/components/Character}/Character.module.scss +6 -2
  135. package/src/{components/RemainingTiles → modals/RemainingTilesModal/components/Character}/Character.tsx +11 -3
  136. package/src/modals/RemainingTilesModal/components/Character/index.ts +1 -0
  137. package/src/modals/RemainingTilesModal/components/index.ts +1 -0
  138. package/src/modals/RemainingTilesModal/index.ts +1 -0
  139. package/src/modals/ResultsModal/ResultsModal.module.scss +7 -0
  140. package/src/modals/ResultsModal/ResultsModal.tsx +58 -0
  141. package/src/modals/ResultsModal/index.ts +1 -0
  142. package/src/modals/SettingsModal/SettingsModal.tsx +34 -0
  143. package/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/AutoGroupTilesSetting.module.scss +0 -0
  144. package/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +1 -2
  145. package/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/constants.ts +0 -0
  146. package/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/index.ts +0 -0
  147. package/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/lib.ts +0 -0
  148. package/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/ConfigSetting.module.scss +0 -0
  149. package/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/ConfigSetting.tsx +1 -2
  150. package/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/index.ts +0 -0
  151. package/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/options.ts +0 -0
  152. package/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/types.ts +0 -0
  153. package/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/LocaleSetting.module.scss +0 -0
  154. package/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/LocaleSetting.tsx +1 -2
  155. package/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/index.ts +0 -0
  156. package/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/options.ts +0 -0
  157. package/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/types.ts +0 -0
  158. package/src/{components/Settings → modals/SettingsModal}/components/index.ts +0 -0
  159. package/src/modals/SettingsModal/index.ts +1 -0
  160. package/src/{components/Words/Words.module.scss → modals/WordsModal/WordsModal.module.scss} +7 -1
  161. package/src/{components/Words/Words.tsx → modals/WordsModal/WordsModal.tsx} +10 -12
  162. package/src/modals/WordsModal/index.ts +1 -0
  163. package/src/modals/index.ts +6 -0
  164. package/src/pages/api/dictionary/[locale]/[word].ts +2 -1
  165. package/src/pages/index.module.scss +6 -4
  166. package/src/pages/index.tsx +63 -26
  167. package/src/parameters/index.ts +28 -6
  168. package/src/state/createAppStore.ts +7 -4
  169. package/src/styles/mixins.scss +15 -13
  170. package/src/styles/variables.scss +15 -17
  171. package/src/types/index.ts +2 -0
  172. package/tsconfig.json +1 -0
  173. package/.next/cache/webpack/client-development/0.pack +0 -0
  174. package/.next/cache/webpack/client-development/1.pack +0 -0
  175. package/.next/cache/webpack/client-development/2.pack +0 -0
  176. package/.next/cache/webpack/client-development/3.pack +0 -0
  177. package/.next/cache/webpack/client-development/4.pack +0 -0
  178. package/.next/cache/webpack/client-development/index.pack +0 -0
  179. package/.next/cache/webpack/client-development/index.pack.old +0 -0
  180. package/.next/cache/webpack/server-development/0.pack +0 -0
  181. package/.next/cache/webpack/server-development/10.pack_ +0 -0
  182. package/.next/cache/webpack/server-development/5.pack_ +0 -0
  183. package/.next/cache/webpack/server-development/8.pack_ +0 -0
  184. package/.next/cache/webpack/server-development/index.pack +0 -0
  185. package/.next/static/FjrbXpI5fkt4lmko-vL_7/_buildManifest.js +0 -1
  186. package/.next/static/chunks/361-d16f336a9752a55a.js +0 -1
  187. package/.next/static/chunks/724-eb48df4d1ba3df8b.js +0 -5
  188. package/.next/static/chunks/amp.js +0 -720
  189. package/.next/static/chunks/main.js +0 -1076
  190. package/.next/static/chunks/pages/_app-959e495f0f221247.js +0 -24
  191. package/.next/static/chunks/pages/_app.js +0 -2121
  192. package/.next/static/chunks/pages/_error.js +0 -28
  193. package/.next/static/chunks/pages/index-1e30dafa41bddb80.js +0 -1
  194. package/.next/static/chunks/pages/index.js +0 -5314
  195. package/.next/static/chunks/react-refresh.js +0 -62
  196. package/.next/static/chunks/webpack.js +0 -1237
  197. package/.next/static/css/aafd07997120f1e4.css +0 -1
  198. package/.next/static/css/c8d26240c04079b9.css +0 -1
  199. package/.next/static/css/eb9d57f7103525ab.css +0 -1
  200. package/.next/static/development/_buildManifest.js +0 -1
  201. package/.next/static/development/_ssgManifest.js +0 -1
  202. package/.next/static/webpack/fb4b50d5e70ee127.webpack.hot-update.json +0 -1
  203. package/.next/static/webpack/pages/index.fb4b50d5e70ee127.hot-update.js +0 -171
  204. package/.next/static/webpack/webpack.fb4b50d5e70ee127.hot-update.js +0 -18
  205. package/src/components/KeyMap/index.ts +0 -1
  206. package/src/components/RemainingTiles/RemainingTiles.module.scss +0 -16
  207. package/src/components/RemainingTiles/index.ts +0 -1
  208. package/src/components/Screen/index.ts +0 -1
  209. package/src/components/Settings/Settings.tsx +0 -35
  210. package/src/components/Settings/index.ts +0 -1
  211. package/src/components/Sidebar/index.ts +0 -1
  212. package/src/components/Splash/index.ts +0 -1
  213. package/src/components/Words/index.ts +0 -1
  214. package/src/hooks/useIsTablet.ts +0 -10
  215. package/src/icons/Play.svg +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/scrabble-solver",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "description": "Scrabble Solver 2 - App",
5
5
  "engines": {
6
6
  "node": ">=16"
@@ -31,14 +31,16 @@
31
31
  "@kamilmielnik/trie": "^2.0.1",
32
32
  "@popperjs/core": "^2.11.6",
33
33
  "@reduxjs/toolkit": "^1.9.2",
34
- "@scrabble-solver/configs": "^2.10.2",
35
- "@scrabble-solver/constants": "^2.10.2",
36
- "@scrabble-solver/dictionaries": "^2.10.2",
37
- "@scrabble-solver/logger": "^2.10.2",
38
- "@scrabble-solver/solver": "^2.10.2",
39
- "@scrabble-solver/types": "^2.10.2",
40
- "@scrabble-solver/word-definitions": "^2.10.2",
34
+ "@scrabble-solver/configs": "^2.10.4",
35
+ "@scrabble-solver/constants": "^2.10.4",
36
+ "@scrabble-solver/dictionaries": "^2.10.4",
37
+ "@scrabble-solver/logger": "^2.10.4",
38
+ "@scrabble-solver/solver": "^2.10.4",
39
+ "@scrabble-solver/types": "^2.10.4",
40
+ "@scrabble-solver/word-definitions": "^2.10.4",
41
41
  "classnames": "^2.3.2",
42
+ "include-media": "^2.0.0",
43
+ "include-media-query-builder": "^1.1.0",
42
44
  "next": "^13.1.6",
43
45
  "normalize.css": "^8.0.1",
44
46
  "react": "^18.2.0",
@@ -74,5 +76,5 @@
74
76
  "sass": "^1.57.1",
75
77
  "workbox-webpack-plugin": "^6.5.4"
76
78
  },
77
- "gitHead": "4feaabfad2a10079c28e04f446c98dbf0383d520"
79
+ "gitHead": "7cce9fa637f3c346b1772d0a2b401d3e271b8e67"
78
80
  }
@@ -2,12 +2,11 @@
2
2
  display: inline-flex;
3
3
  align-items: center;
4
4
  justify-content: center;
5
- padding: var(--spacing--xs) var(--spacing--s);
5
+ padding: var(--spacing--xs) var(--spacing--m);
6
+ border: var(--border);
6
7
  border-radius: var(--border--radius);
7
- background-color: var(--color--foreground--secondary);
8
- box-shadow: va(--box-shadow);
8
+ background-color: var(--color--background--overlay);
9
9
  line-height: var(--line-height);
10
- font-size: var(--font--size--s);
10
+ font-size: var(--font--size--m);
11
11
  font-weight: bold;
12
- color: white;
13
12
  }
@@ -1,4 +1,4 @@
1
- import { Cell } from '@scrabble-solver/types';
1
+ import { Cell as CellModel } from '@scrabble-solver/types';
2
2
  import classNames from 'classnames';
3
3
  import {
4
4
  ChangeEventHandler,
@@ -13,16 +13,16 @@ import {
13
13
  import { Direction } from 'types';
14
14
 
15
15
  import styles from './Board.module.scss';
16
- import { Cell as CellComponent } from './components';
16
+ import { Cell } from './components';
17
17
 
18
18
  interface Props {
19
19
  className?: string;
20
20
  cellSize: number;
21
- center: Cell;
21
+ center: CellModel;
22
22
  direction: Direction;
23
23
  innerRef?: Ref<HTMLDivElement>;
24
24
  refs: RefObject<HTMLInputElement>[][];
25
- rows: Cell[][];
25
+ rows: CellModel[][];
26
26
  onChange: ChangeEventHandler<HTMLInputElement>;
27
27
  onDirectionToggle: () => void;
28
28
  onFocus: (x: number, y: number) => void;
@@ -48,7 +48,7 @@ const BoardPure: FunctionComponent<Props> = ({
48
48
  {rows.map((cells, y) => (
49
49
  <div className={styles.row} key={y}>
50
50
  {cells.map((cell, x) => (
51
- <CellComponent
51
+ <Cell
52
52
  className={styles.cell}
53
53
  cell={cell}
54
54
  direction={direction}
@@ -8,17 +8,30 @@ $icon-size: 16px;
8
8
  position: relative;
9
9
  display: table-cell;
10
10
  background-color: white;
11
- border-right: var(--border--width) dotted var(--border--color--light);
12
11
  border-bottom: var(--border--width) dotted var(--border--color--light);
13
12
  transition: var(--transition);
14
13
  background-clip: padding-box;
15
14
 
15
+ [dir='ltr'] & {
16
+ border-right: var(--border--width) dotted var(--border--color--light);
17
+ }
18
+
19
+ [dir='rtl'] & {
20
+ border-left: var(--border--width) dotted var(--border--color--light);
21
+ }
22
+
16
23
  &.bottom {
17
24
  border-bottom: none;
18
25
  }
19
26
 
20
27
  &.right {
21
- border-right: none;
28
+ [dir='ltr'] & {
29
+ border-right: none;
30
+ }
31
+
32
+ [dir='rtl'] & {
33
+ border-left: none;
34
+ }
22
35
  }
23
36
 
24
37
  &.bonusStart {
@@ -1,23 +1,23 @@
1
1
  @import 'styles/mixins';
2
2
 
3
- $size: 32px;
4
-
5
3
  .button {
6
4
  @include button-reset;
7
5
  @include focus-effect;
8
6
 
9
7
  display: inline-block;
10
- transition: var(--transition);
8
+ padding: var(--spacing--m) var(--spacing--l);
9
+ border: var(--border);
11
10
  border-radius: var(--border--radius);
12
11
  box-shadow: none;
13
12
  color: var(--color--inactive);
13
+ transition: var(--transition);
14
14
  cursor: pointer;
15
- opacity: 0.9;
16
15
 
17
16
  &,
18
17
  &:active,
19
18
  &:focus,
20
19
  &:hover {
20
+ text-decoration: none;
21
21
  background-color: var(--color--primary);
22
22
  box-shadow: var(--box-shadow);
23
23
  color: white;
@@ -32,53 +32,25 @@ $size: 32px;
32
32
  }
33
33
  }
34
34
 
35
- &:disabled {
36
- background-color: var(--color--background);
37
- color: var(--color--inactive);
35
+ &[disabled] {
36
+ opacity: var(--opacity--disabled);
38
37
  box-shadow: none;
39
38
  cursor: not-allowed;
40
-
41
- .icon {
42
- transform: scale(1);
43
- }
44
- }
45
-
46
- &:hover {
47
- opacity: 1;
48
-
49
- &:not(:disabled) {
50
- .icon {
51
- transform: scale(1.1);
52
- }
53
- }
54
39
  }
55
40
  }
56
41
 
57
42
  .content {
58
43
  display: flex;
59
44
  align-items: center;
60
- padding: var(--spacing--xs) var(--spacing--m);
61
- }
62
-
63
- .icon,
64
- .label {
65
- transition: var(--transition);
45
+ gap: var(--spacing--m);
66
46
  }
67
47
 
68
48
  .icon {
69
- width: $size;
70
- height: $size;
71
- pointer-events: none;
72
- transition: var(--transition);
73
- transform: scale(1);
74
- color: inherit;
49
+ width: var(--button--icon--size);
50
+ height: var(--button--icon--size);
75
51
  }
76
52
 
77
53
  .label {
78
- padding: 0 var(--spacing--m);
79
- transition: var(--transition);
80
- font-size: var(--font--size--m);
54
+ font-size: var(--font--size--h3);
81
55
  text-transform: uppercase;
82
- pointer-events: none;
83
- user-select: none;
84
56
  }
@@ -6,19 +6,20 @@ import { useTooltip } from '../Tooltip';
6
6
  import styles from './Button.module.scss';
7
7
 
8
8
  interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
9
- Icon: FunctionComponent<SVGAttributes<SVGElement>>;
10
- onClick: MouseEventHandler<HTMLButtonElement>;
9
+ Icon?: FunctionComponent<SVGAttributes<SVGElement>>;
10
+ iconClassName?: string;
11
11
  tooltip?: ReactNode;
12
+ onClick: MouseEventHandler<HTMLButtonElement>;
12
13
  }
13
14
 
14
- const Button: FunctionComponent<Props> = ({ children, className, Icon, tooltip, ...props }) => {
15
+ const Button: FunctionComponent<Props> = ({ children, className, Icon, iconClassName, tooltip, ...props }) => {
15
16
  const triggerProps = useTooltip(tooltip, props);
16
17
 
17
18
  return (
18
19
  <button className={classNames(styles.button, className)} type="button" {...props} {...triggerProps}>
19
20
  <span className={styles.content}>
20
- <span className={styles.label}>{children}</span>
21
- <Icon className={styles.icon} />
21
+ {Icon && <Icon className={classNames(styles.icon, iconClassName)} />}
22
+ {children && <span className={styles.label}>{children}</span>}
22
23
  </span>
23
24
  </button>
24
25
  );
@@ -1,10 +1,9 @@
1
1
  .dictionary {
2
2
  position: relative;
3
- min-height: calc(var(--dictionary--height) - var(--text-input--height));
3
+ height: var(--dictionary--height);
4
4
  overflow-y: auto;
5
5
  word-break: break-word;
6
6
  transition: var(--transition);
7
- font-size: var(--font--size--s);
8
7
  }
9
8
 
10
9
  .result {
@@ -25,11 +25,7 @@ const Dictionary: FunctionComponent<Props> = ({ className }) => {
25
25
  [styles.isNotAllowed]: isFirstAllowed === false,
26
26
  })}
27
27
  >
28
- {typeof error !== 'undefined' && (
29
- <EmptyState className={styles.emptyState} type="error">
30
- {error.message}
31
- </EmptyState>
32
- )}
28
+ {typeof error !== 'undefined' && <EmptyState variant="error">{error.message}</EmptyState>}
33
29
 
34
30
  {results.map(({ definitions, exists, isAllowed, word }) => (
35
31
  <div
@@ -40,7 +36,7 @@ const Dictionary: FunctionComponent<Props> = ({ className }) => {
40
36
  key={word}
41
37
  >
42
38
  {typeof word === 'undefined' && (
43
- <EmptyState type="info">{translate('dictionary.empty-state.uninitialized')}</EmptyState>
39
+ <EmptyState variant="info">{translate('dictionary.empty-state.uninitialized')}</EmptyState>
44
40
  )}
45
41
 
46
42
  {typeof word !== 'undefined' && (
@@ -1,9 +1,7 @@
1
1
  @import 'styles/mixins';
2
2
 
3
3
  .dictionaryInput {
4
- &:focus-within {
5
- @include focus-effect;
6
- }
4
+ @include focus-effect;
7
5
  }
8
6
 
9
7
  .input {
@@ -1,15 +1,14 @@
1
1
  .emptyState {
2
- margin: 0 auto;
3
- max-width: calc(2 * var(--sidebar--width) / 3);
4
2
  padding: var(--spacing--xl);
5
3
  font-family: var(--font--family);
6
4
  color: var(--color--foreground--secondary);
7
5
  text-align: center;
8
6
  text-transform: none;
7
+ }
9
8
 
10
- .tiles {
11
- margin-bottom: var(--spacing--m);
12
- height: 32px;
13
- overflow: visible;
14
- }
9
+ .tiles {
10
+ display: inline-block;
11
+ margin-bottom: var(--spacing--m);
12
+ height: 40px;
13
+ overflow: visible;
15
14
  }
@@ -13,34 +13,34 @@ import styles from './EmptyState.module.scss';
13
13
  interface Props {
14
14
  children: ReactNode;
15
15
  className?: string;
16
- type: 'error' | 'info' | 'success' | 'warning';
16
+ variant: 'error' | 'info' | 'success' | 'warning';
17
17
  }
18
18
 
19
- const TITLE_KEY_PER_TYPE: Record<Props['type'], keyof Translations> = {
19
+ const TITLE_KEY_PER_TYPE: Record<Props['variant'], keyof Translations> = {
20
20
  error: 'empty-state.error',
21
21
  info: 'empty-state.info',
22
22
  success: 'empty-state.success',
23
23
  warning: 'empty-state.warning',
24
24
  };
25
25
 
26
- const COLORS_PER_TYPE: Record<Props['type'], string> = {
26
+ const COLORS_PER_TYPE: Record<Props['variant'], string> = {
27
27
  error: COLOR_RED,
28
28
  info: COLOR_BLUE,
29
29
  success: COLOR_GREEN,
30
30
  warning: COLOR_YELLOW,
31
31
  };
32
32
 
33
- const EmptyState: FunctionComponent<Props> = ({ className, children, type }) => {
33
+ const EmptyState: FunctionComponent<Props> = ({ children, className, variant }) => {
34
34
  const translate = useTranslate();
35
35
  const locale = useTypedSelector(selectLocale);
36
36
  const { direction } = LOCALE_FEATURES[locale];
37
- const title = useMemo(() => translate(TITLE_KEY_PER_TYPE[type]), [translate]);
37
+ const title = useMemo(() => translate(TITLE_KEY_PER_TYPE[variant]), [translate]);
38
38
  const message = direction === 'ltr' ? title : title.split('').reverse().join('');
39
39
  const content = useMemo(() => [[message.toUpperCase()]], [title]);
40
40
 
41
41
  return (
42
42
  <div className={classNames(styles.emptyState, className)}>
43
- <PlainTiles className={styles.tiles} color={COLORS_PER_TYPE[type]} content={content} />
43
+ <PlainTiles className={styles.tiles} color={COLORS_PER_TYPE[variant]} content={content} />
44
44
 
45
45
  <div className={styles.content}>{children}</div>
46
46
  </div>
@@ -13,7 +13,6 @@ $icon-size: 15px;
13
13
  border-radius: var(--border--radius);
14
14
  box-shadow: var(--box-shadow);
15
15
  font-family: var(--font--family--monospace);
16
- font-size: var(--font--size--s);
17
16
  line-height: calc(#{$key-size} - 2 * (var(--spacing--s) + var(--border--width)));
18
17
  vertical-align: middle;
19
18
  text-align: center;
@@ -4,7 +4,7 @@ $loading-duration: 250ms;
4
4
  $loaded-duration: 100ms;
5
5
  $hiding-duration: 200ms;
6
6
 
7
- .splash {
7
+ .logoSplashScreen {
8
8
  display: flex;
9
9
  align-items: center;
10
10
  justify-content: center;
@@ -2,9 +2,9 @@ import classNames from 'classnames';
2
2
  import { AnimationEventHandler, FunctionComponent } from 'react';
3
3
 
4
4
  import Logo from '../Logo';
5
- import Screen from '../Screen';
5
+ import SplashScreen from '../SplashScreen';
6
6
 
7
- import styles from './Splash.module.scss';
7
+ import styles from './LogoSplashScreen.module.scss';
8
8
 
9
9
  interface Props {
10
10
  className?: string;
@@ -12,9 +12,9 @@ interface Props {
12
12
  onAnimationEnd?: AnimationEventHandler<HTMLDivElement>;
13
13
  }
14
14
 
15
- const Splash: FunctionComponent<Props> = ({ className, forceShow, onAnimationEnd }) => (
16
- <Screen
17
- className={classNames(styles.splash, className, {
15
+ const LogoSplashScreen: FunctionComponent<Props> = ({ className, forceShow, onAnimationEnd }) => (
16
+ <SplashScreen
17
+ className={classNames(styles.logoSplashScreen, className, {
18
18
  [styles.animated]: !forceShow,
19
19
  })}
20
20
  onAnimationEnd={onAnimationEnd}
@@ -25,7 +25,7 @@ const Splash: FunctionComponent<Props> = ({ className, forceShow, onAnimationEnd
25
25
  </div>
26
26
 
27
27
  <h1 className={styles.author}>by Kamil Mielnik</h1>
28
- </Screen>
28
+ </SplashScreen>
29
29
  );
30
30
 
31
- export default Splash;
31
+ export default LogoSplashScreen;
@@ -0,0 +1 @@
1
+ export { default } from './LogoSplashScreen';
@@ -1,8 +1,5 @@
1
1
  @import 'styles/mixins';
2
2
 
3
- $z-index: 100;
4
- $width: 370px;
5
-
6
3
  .modal,
7
4
  .closeButton {
8
5
  top: 0;
@@ -18,9 +15,9 @@ $width: 370px;
18
15
 
19
16
  .modal {
20
17
  position: fixed;
21
- z-index: $z-index;
18
+ z-index: var(--z-index--modal);
22
19
  height: 100vh;
23
- width: $width;
20
+ width: var(--modal--width);
24
21
  padding: 0;
25
22
  border-radius: 0;
26
23
  border: none;
@@ -28,10 +25,14 @@ $width: 370px;
28
25
  &:focus {
29
26
  outline: none;
30
27
  }
28
+
29
+ @include media('<s') {
30
+ --modal--width: 100%;
31
+ }
31
32
  }
32
33
 
33
34
  .afterOpen {
34
- .sidebar {
35
+ .container {
35
36
  [dir='ltr'] &,
36
37
  [dir='rtl'] & {
37
38
  transform: translateX(0);
@@ -41,15 +42,15 @@ $width: 370px;
41
42
  }
42
43
 
43
44
  .beforeClose {
44
- .sidebar {
45
+ .container {
45
46
  opacity: 0;
46
47
 
47
48
  [dir='ltr'] & {
48
- transform: translateX($width);
49
+ transform: translateX(var(--modal--width));
49
50
  }
50
51
 
51
52
  [dir='rtl'] & {
52
- transform: translateX(-$width);
53
+ transform: translateX(calc(-1 * var(--modal--width)));
53
54
  }
54
55
  }
55
56
  }
@@ -58,30 +59,34 @@ $width: 370px;
58
59
  background-color: transparent;
59
60
  }
60
61
 
61
- .sidebar {
62
+ .container {
62
63
  display: flex;
63
64
  flex-direction: column;
64
65
  height: 100%;
65
66
  background-color: var(--color--background);
66
- box-shadow: var(--box-shadow--left);
67
67
  transition: var(--transition);
68
68
  transition-duration: var(--transition--duration--long);
69
- transform: translateX($width);
69
+ transform: translateX(var(--modal--width));
70
70
  opacity: 0;
71
71
 
72
72
  [dir='ltr'] & {
73
- transform: translateX($width);
73
+ transform: translateX(var(--modal--width));
74
+ box-shadow: var(--box-shadow--offset--negative) 0 var(--box-shadow--blur) var(--box-shadow--spread)
75
+ var(--box-shadow--color);
74
76
  }
75
77
 
76
78
  [dir='rtl'] & {
77
- transform: translateX(-$width);
79
+ transform: translateX(calc(-1 * var(--modal--width)));
80
+ box-shadow: var(--box-shadow--offset) 0 var(--box-shadow--blur) var(--box-shadow--spread) var(--box-shadow--color);
78
81
  }
79
82
  }
80
83
 
81
84
  .header {
82
- flex: 0 0 auto;
83
85
  position: relative;
86
+ z-index: 1;
87
+ flex: 0 0 auto;
84
88
  padding: var(--spacing--l);
89
+ background-color: var(--color--background);
85
90
  }
86
91
 
87
92
  .title {
@@ -89,24 +94,24 @@ $width: 370px;
89
94
  font-weight: 300;
90
95
 
91
96
  [dir='ltr'] & {
92
- padding-right: calc(var(--square-button-size) + var(--spacing--s));
97
+ padding-right: calc(var(--square-button--size) + var(--spacing--s));
93
98
  }
94
99
 
95
100
  [dir='rtl'] & {
96
- padding-left: calc(var(--square-button-size) + var(--spacing--s));
101
+ padding-left: calc(var(--square-button--size) + var(--spacing--s));
97
102
  }
98
103
  }
99
104
 
100
105
  .closeButton {
101
106
  position: absolute !important;
102
- z-index: $z-index + 1;
107
+ z-index: var(--z-index--close-button);
103
108
  margin: var(--spacing--l);
104
109
  }
105
110
 
106
111
  .content {
107
- flex: 1;
108
112
  position: relative;
113
+ flex: 1;
114
+ margin-top: calc(-1 * var(--spacing--l));
109
115
  padding: var(--spacing--l);
110
- padding-top: 0;
111
116
  overflow: auto;
112
117
  }
@@ -1,16 +1,16 @@
1
1
  import classNames from 'classnames';
2
2
  import { FunctionComponent, ReactNode, useEffect, useState } from 'react';
3
- import Modal from 'react-modal';
3
+ import ReactModal from 'react-modal';
4
4
  import { useKey } from 'react-use';
5
5
 
6
- import { CrossFill } from 'icons';
6
+ import { CrossSquareFill } from 'icons';
7
7
  import { TRANSITION_DURATION_LONG } from 'parameters';
8
8
  import { useTranslate } from 'state';
9
9
 
10
10
  import SquareButton from '../SquareButton';
11
11
 
12
12
  import { Section } from './components';
13
- import styles from './Sidebar.module.scss';
13
+ import styles from './Modal.module.scss';
14
14
 
15
15
  export interface Props {
16
16
  children: ReactNode;
@@ -20,7 +20,7 @@ export interface Props {
20
20
  onClose: () => void;
21
21
  }
22
22
 
23
- const Sidebar: FunctionComponent<Props> = ({ children, className, isOpen, title, onClose }) => {
23
+ const Modal: FunctionComponent<Props> = ({ children, className, isOpen, title, onClose }) => {
24
24
  const translate = useTranslate();
25
25
  const [shouldReturnFocusAfterClose, setShouldReturnFocusAfterClose] = useState(true);
26
26
 
@@ -41,7 +41,7 @@ const Sidebar: FunctionComponent<Props> = ({ children, className, isOpen, title,
41
41
  }, [isOpen]);
42
42
 
43
43
  return (
44
- <Modal
44
+ <ReactModal
45
45
  className={{
46
46
  afterOpen: styles.afterOpen,
47
47
  base: styles.modal,
@@ -54,13 +54,13 @@ const Sidebar: FunctionComponent<Props> = ({ children, className, isOpen, title,
54
54
  shouldReturnFocusAfterClose={shouldReturnFocusAfterClose}
55
55
  onRequestClose={onClose}
56
56
  >
57
- <div className={classNames(styles.sidebar, className)}>
57
+ <div className={classNames(styles.container, className)}>
58
58
  <div className={styles.header}>
59
59
  <h1 className={styles.title}>{title}</h1>
60
60
 
61
61
  <SquareButton
62
62
  className={styles.closeButton}
63
- Icon={CrossFill}
63
+ Icon={CrossSquareFill}
64
64
  tooltip={translate('common.close')}
65
65
  onClick={onClose}
66
66
  />
@@ -68,10 +68,10 @@ const Sidebar: FunctionComponent<Props> = ({ children, className, isOpen, title,
68
68
 
69
69
  <div className={styles.content}>{children}</div>
70
70
  </div>
71
- </Modal>
71
+ </ReactModal>
72
72
  );
73
73
  };
74
74
 
75
- export default Object.assign(Sidebar, {
75
+ export default Object.assign(Modal, {
76
76
  Section,
77
77
  });
@@ -0,0 +1 @@
1
+ export { default } from './Modal';
@@ -1,8 +1,8 @@
1
1
  import classNames from 'classnames';
2
2
  import { FunctionComponent } from 'react';
3
3
 
4
- import { useIsTouchDevice } from 'hooks';
5
- import { BookHalf, Cog, Eraser, Github, Keyboard, Sack } from 'icons';
4
+ import { useIsTouchDevice, useMediaQuery } from 'hooks';
5
+ import { CardChecklist, Cog, Eraser, Github, Keyboard, List, Sack } from 'icons';
6
6
  import { GITHUB_PROJECT_URL } from 'parameters';
7
7
  import { selectHasInvalidWords, selectHasOverusedTiles, useTranslate, useTypedSelector } from 'state';
8
8
 
@@ -13,6 +13,7 @@ import styles from './NavButtons.module.scss';
13
13
  interface Props {
14
14
  onClear: () => void;
15
15
  onShowKeyMap: () => void;
16
+ onShowMenu: () => void;
16
17
  onShowRemainingTiles: () => void;
17
18
  onShowSettings: () => void;
18
19
  onShowWords: () => void;
@@ -21,6 +22,7 @@ interface Props {
21
22
  const NavButtons: FunctionComponent<Props> = ({
22
23
  onClear,
23
24
  onShowKeyMap,
25
+ onShowMenu,
24
26
  onShowRemainingTiles,
25
27
  onShowSettings,
26
28
  onShowWords,
@@ -29,6 +31,23 @@ const NavButtons: FunctionComponent<Props> = ({
29
31
  const hasOverusedTiles = useTypedSelector(selectHasOverusedTiles);
30
32
  const hasInvalidWords = useTypedSelector(selectHasInvalidWords);
31
33
  const isTouchDevice = useIsTouchDevice();
34
+ const isLessThanS = useMediaQuery('<s');
35
+
36
+ if (isLessThanS) {
37
+ return (
38
+ <div className={styles.navButtons}>
39
+ <div className={styles.group}>
40
+ <SquareButton className={styles.button} Icon={Eraser} tooltip={translate('common.clear')} onClick={onClear} />
41
+ </div>
42
+
43
+ <div className={styles.separator} />
44
+
45
+ <div className={styles.group}>
46
+ <SquareButton className={styles.button} Icon={List} tooltip={translate('menu')} onClick={onShowMenu} />
47
+ </div>
48
+ </div>
49
+ );
50
+ }
32
51
 
33
52
  return (
34
53
  <div className={styles.navButtons}>
@@ -52,7 +71,7 @@ const NavButtons: FunctionComponent<Props> = ({
52
71
  className={classNames(styles.button, {
53
72
  [styles.error]: hasInvalidWords,
54
73
  })}
55
- Icon={BookHalf}
74
+ Icon={CardChecklist}
56
75
  tooltip={translate('words')}
57
76
  onClick={onShowWords}
58
77
  />