scrabble-solver 2.10.5 → 2.10.6

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 (75) hide show
  1. package/lerna.json +1 -1
  2. package/package.json +10 -10
  3. package/packages/configs/package-lock.json +4 -4
  4. package/packages/configs/package.json +3 -3
  5. package/packages/constants/package-lock.json +2 -2
  6. package/packages/constants/package.json +1 -1
  7. package/packages/dictionaries/package-lock.json +2 -2
  8. package/packages/dictionaries/package.json +4 -4
  9. package/packages/logger/package-lock.json +2 -2
  10. package/packages/logger/package.json +1 -1
  11. package/packages/scrabble-solver/.next/BUILD_ID +1 -1
  12. package/packages/scrabble-solver/.next/build-manifest.json +9 -9
  13. package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
  14. package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
  15. package/packages/scrabble-solver/.next/cache/next-server.js.nft.json +1 -1
  16. package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
  17. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
  18. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/0.pack +0 -0
  19. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
  20. package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
  21. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
  22. package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
  23. package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
  24. package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
  25. package/packages/scrabble-solver/.next/server/chunks/176.js +343 -209
  26. package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
  27. package/packages/scrabble-solver/.next/server/pages/404.html +2 -2
  28. package/packages/scrabble-solver/.next/server/pages/404.js.nft.json +1 -1
  29. package/packages/scrabble-solver/.next/server/pages/500.html +2 -2
  30. package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
  31. package/packages/scrabble-solver/.next/server/pages/index.html +2 -2
  32. package/packages/scrabble-solver/.next/server/pages/index.js +4 -4
  33. package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
  34. package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
  35. package/packages/scrabble-solver/.next/server/pages-manifest.json +2 -2
  36. package/packages/scrabble-solver/.next/static/chunks/791-93aa8b8c22e488ac.js +1 -0
  37. package/packages/scrabble-solver/.next/static/chunks/pages/{404-7619583a9e7188b1.js → 404-ff35a4cf7f1ec85a.js} +1 -1
  38. package/packages/scrabble-solver/.next/static/chunks/pages/index-ded620fd5df96be0.js +1 -0
  39. package/packages/scrabble-solver/.next/static/css/4482c4a0064d3807.css +1 -0
  40. package/packages/scrabble-solver/.next/static/css/a943dd97164732d4.css +1 -0
  41. package/packages/scrabble-solver/.next/static/iL0av55MV28b0MXfhKKt2/_buildManifest.js +1 -0
  42. package/packages/scrabble-solver/.next/trace +55 -55
  43. package/packages/scrabble-solver/package-lock.json +37 -37
  44. package/packages/scrabble-solver/package.json +13 -13
  45. package/packages/scrabble-solver/src/components/Button/Button.module.scss +2 -5
  46. package/packages/scrabble-solver/src/components/Solver/Solver.module.scss +9 -21
  47. package/packages/scrabble-solver/src/components/Solver/Solver.tsx +12 -48
  48. package/packages/scrabble-solver/src/components/Solver/components/MobileControls/MobileControls.tsx +62 -0
  49. package/packages/scrabble-solver/src/components/Solver/components/MobileControls/index.ts +1 -0
  50. package/packages/scrabble-solver/src/components/{ResultCandidatePicker → Solver/components/ResultCandidatePicker}/ResultCandidatePicker.module.scss +47 -3
  51. package/packages/scrabble-solver/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +75 -0
  52. package/packages/scrabble-solver/src/components/Solver/components/index.ts +2 -0
  53. package/packages/scrabble-solver/src/components/SquareButton/SquareButton.module.scss +1 -2
  54. package/packages/scrabble-solver/src/components/index.ts +0 -1
  55. package/packages/scrabble-solver/src/icons/ChevronLeft.svg +4 -0
  56. package/packages/scrabble-solver/src/icons/ChevronRight.svg +4 -0
  57. package/packages/scrabble-solver/src/icons/index.ts +2 -0
  58. package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.module.scss +2 -3
  59. package/packages/scrabble-solver/src/styles/mixins.scss +6 -0
  60. package/packages/solver/package-lock.json +2 -2
  61. package/packages/solver/package.json +5 -5
  62. package/packages/types/package-lock.json +3 -3
  63. package/packages/types/package.json +2 -2
  64. package/packages/word-definitions/package-lock.json +2 -2
  65. package/packages/word-definitions/package.json +2 -2
  66. package/packages/word-lists/package-lock.json +2 -2
  67. package/packages/word-lists/package.json +2 -2
  68. package/packages/scrabble-solver/.next/static/WILX-RgqlLTd4ZoPs8C_E/_buildManifest.js +0 -1
  69. package/packages/scrabble-solver/.next/static/chunks/144-6768fe9a92865ec8.js +0 -1
  70. package/packages/scrabble-solver/.next/static/chunks/pages/index-1a6bbb880f28606a.js +0 -1
  71. package/packages/scrabble-solver/.next/static/css/d80ffccf2315791a.css +0 -1
  72. package/packages/scrabble-solver/.next/static/css/e737d5d7fbed2434.css +0 -1
  73. package/packages/scrabble-solver/src/components/ResultCandidatePicker/ResultCandidatePicker.tsx +0 -38
  74. /package/packages/scrabble-solver/.next/static/{WILX-RgqlLTd4ZoPs8C_E → iL0av55MV28b0MXfhKKt2}/_ssgManifest.js +0 -0
  75. /package/packages/scrabble-solver/src/components/{ResultCandidatePicker → Solver/components/ResultCandidatePicker}/index.ts +0 -0
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@scrabble-solver/scrabble-solver",
3
- "version": "2.10.5",
3
+ "version": "2.10.6",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/scrabble-solver",
9
- "version": "2.10.5",
9
+ "version": "2.10.6",
10
10
  "license": "CC BY-NC-ND 4.0",
11
11
  "dependencies": {
12
12
  "@kamilmielnik/trie": "^2.0.1",
13
13
  "@popperjs/core": "^2.11.6",
14
- "@reduxjs/toolkit": "^1.9.2",
14
+ "@reduxjs/toolkit": "^1.9.3",
15
15
  "classnames": "^2.3.2",
16
16
  "include-media": "^2.0.0",
17
17
  "include-media-query-builder": "^1.1.0",
@@ -37,17 +37,17 @@
37
37
  "devDependencies": {
38
38
  "@svgr/webpack": "^6.5.1",
39
39
  "@types/classnames": "^2.3.0",
40
- "@types/react": "^18.0.27",
41
- "@types/react-dom": "^18.0.10",
40
+ "@types/react": "^18.0.28",
41
+ "@types/react-dom": "^18.0.11",
42
42
  "@types/react-modal": "^3.13.1",
43
43
  "@types/react-portal": "^4.0.4",
44
44
  "@types/react-redux": "^7.1.25",
45
45
  "@types/react-window": "^1.8.5",
46
46
  "@types/redux": "^3.6.31",
47
47
  "@types/redux-saga": "^0.10.5",
48
- "@types/uuid": "^9.0.0",
48
+ "@types/uuid": "^9.0.1",
49
49
  "env-cmd": "^10.1.0",
50
- "sass": "^1.57.1",
50
+ "sass": "^1.58.3",
51
51
  "workbox-webpack-plugin": "^6.5.4"
52
52
  },
53
53
  "engines": {
@@ -2157,9 +2157,9 @@
2157
2157
  "integrity": "sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA=="
2158
2158
  },
2159
2159
  "node_modules/@reduxjs/toolkit": {
2160
- "version": "1.9.2",
2161
- "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz",
2162
- "integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==",
2160
+ "version": "1.9.3",
2161
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.3.tgz",
2162
+ "integrity": "sha512-GU2TNBQVofL09VGmuSioNPQIu6Ml0YLf4EJhgj0AvBadRlCGzUWet8372LjvO4fqKZF2vH1xU0htAa7BrK9pZg==",
2163
2163
  "dependencies": {
2164
2164
  "immer": "^9.0.16",
2165
2165
  "redux": "^4.2.0",
@@ -2622,9 +2622,9 @@
2622
2622
  "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
2623
2623
  },
2624
2624
  "node_modules/@types/react": {
2625
- "version": "18.0.27",
2626
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
2627
- "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
2625
+ "version": "18.0.28",
2626
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
2627
+ "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
2628
2628
  "dependencies": {
2629
2629
  "@types/prop-types": "*",
2630
2630
  "@types/scheduler": "*",
@@ -2632,9 +2632,9 @@
2632
2632
  }
2633
2633
  },
2634
2634
  "node_modules/@types/react-dom": {
2635
- "version": "18.0.10",
2636
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz",
2637
- "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==",
2635
+ "version": "18.0.11",
2636
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz",
2637
+ "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==",
2638
2638
  "devOptional": true,
2639
2639
  "dependencies": {
2640
2640
  "@types/react": "*"
@@ -2720,9 +2720,9 @@
2720
2720
  "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
2721
2721
  },
2722
2722
  "node_modules/@types/uuid": {
2723
- "version": "9.0.0",
2724
- "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.0.tgz",
2725
- "integrity": "sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==",
2723
+ "version": "9.0.1",
2724
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
2725
+ "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
2726
2726
  "dev": true
2727
2727
  },
2728
2728
  "node_modules/@webassemblyjs/ast": {
@@ -5635,9 +5635,9 @@
5635
5635
  }
5636
5636
  },
5637
5637
  "node_modules/sass": {
5638
- "version": "1.57.1",
5639
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz",
5640
- "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==",
5638
+ "version": "1.58.3",
5639
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.3.tgz",
5640
+ "integrity": "sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==",
5641
5641
  "devOptional": true,
5642
5642
  "dependencies": {
5643
5643
  "chokidar": ">=3.0.0 <4.0.0",
@@ -8184,9 +8184,9 @@
8184
8184
  "integrity": "sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA=="
8185
8185
  },
8186
8186
  "@reduxjs/toolkit": {
8187
- "version": "1.9.2",
8188
- "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz",
8189
- "integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==",
8187
+ "version": "1.9.3",
8188
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.3.tgz",
8189
+ "integrity": "sha512-GU2TNBQVofL09VGmuSioNPQIu6Ml0YLf4EJhgj0AvBadRlCGzUWet8372LjvO4fqKZF2vH1xU0htAa7BrK9pZg==",
8190
8190
  "requires": {
8191
8191
  "immer": "^9.0.16",
8192
8192
  "redux": "^4.2.0",
@@ -8484,9 +8484,9 @@
8484
8484
  "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
8485
8485
  },
8486
8486
  "@types/react": {
8487
- "version": "18.0.27",
8488
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
8489
- "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
8487
+ "version": "18.0.28",
8488
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
8489
+ "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
8490
8490
  "requires": {
8491
8491
  "@types/prop-types": "*",
8492
8492
  "@types/scheduler": "*",
@@ -8494,9 +8494,9 @@
8494
8494
  }
8495
8495
  },
8496
8496
  "@types/react-dom": {
8497
- "version": "18.0.10",
8498
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz",
8499
- "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==",
8497
+ "version": "18.0.11",
8498
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz",
8499
+ "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==",
8500
8500
  "devOptional": true,
8501
8501
  "requires": {
8502
8502
  "@types/react": "*"
@@ -8581,9 +8581,9 @@
8581
8581
  "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
8582
8582
  },
8583
8583
  "@types/uuid": {
8584
- "version": "9.0.0",
8585
- "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.0.tgz",
8586
- "integrity": "sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==",
8584
+ "version": "9.0.1",
8585
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
8586
+ "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
8587
8587
  "dev": true
8588
8588
  },
8589
8589
  "@webassemblyjs/ast": {
@@ -10769,9 +10769,9 @@
10769
10769
  }
10770
10770
  },
10771
10771
  "sass": {
10772
- "version": "1.57.1",
10773
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz",
10774
- "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==",
10772
+ "version": "1.58.3",
10773
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.3.tgz",
10774
+ "integrity": "sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==",
10775
10775
  "devOptional": true,
10776
10776
  "requires": {
10777
10777
  "chokidar": ">=3.0.0 <4.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/scrabble-solver",
3
- "version": "2.10.5",
3
+ "version": "2.10.6",
4
4
  "description": "Scrabble Solver 2 - App",
5
5
  "engines": {
6
6
  "node": ">=16"
@@ -30,14 +30,14 @@
30
30
  "dependencies": {
31
31
  "@kamilmielnik/trie": "^2.0.1",
32
32
  "@popperjs/core": "^2.11.6",
33
- "@reduxjs/toolkit": "^1.9.2",
34
- "@scrabble-solver/configs": "^2.10.5",
35
- "@scrabble-solver/constants": "^2.10.5",
36
- "@scrabble-solver/dictionaries": "^2.10.5",
37
- "@scrabble-solver/logger": "^2.10.5",
38
- "@scrabble-solver/solver": "^2.10.5",
39
- "@scrabble-solver/types": "^2.10.5",
40
- "@scrabble-solver/word-definitions": "^2.10.5",
33
+ "@reduxjs/toolkit": "^1.9.3",
34
+ "@scrabble-solver/configs": "^2.10.6",
35
+ "@scrabble-solver/constants": "^2.10.6",
36
+ "@scrabble-solver/dictionaries": "^2.10.6",
37
+ "@scrabble-solver/logger": "^2.10.6",
38
+ "@scrabble-solver/solver": "^2.10.6",
39
+ "@scrabble-solver/types": "^2.10.6",
40
+ "@scrabble-solver/word-definitions": "^2.10.6",
41
41
  "classnames": "^2.3.2",
42
42
  "include-media": "^2.0.0",
43
43
  "include-media-query-builder": "^1.1.0",
@@ -63,17 +63,17 @@
63
63
  "devDependencies": {
64
64
  "@svgr/webpack": "^6.5.1",
65
65
  "@types/classnames": "^2.3.0",
66
- "@types/react": "^18.0.27",
67
- "@types/react-dom": "^18.0.10",
66
+ "@types/react": "^18.0.28",
67
+ "@types/react-dom": "^18.0.11",
68
68
  "@types/react-modal": "^3.13.1",
69
69
  "@types/react-portal": "^4.0.4",
70
70
  "@types/react-redux": "^7.1.25",
71
71
  "@types/react-window": "^1.8.5",
72
72
  "@types/redux": "^3.6.31",
73
73
  "@types/redux-saga": "^0.10.5",
74
- "@types/uuid": "^9.0.0",
74
+ "@types/uuid": "^9.0.1",
75
75
  "env-cmd": "^10.1.0",
76
- "sass": "^1.57.1",
76
+ "sass": "^1.58.3",
77
77
  "workbox-webpack-plugin": "^6.5.4"
78
78
  },
79
79
  "gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
@@ -8,7 +8,6 @@
8
8
  padding: var(--spacing--m) var(--spacing--l);
9
9
  border: var(--border);
10
10
  border-radius: var(--border--radius);
11
- color: var(--color--inactive);
12
11
  text-transform: uppercase;
13
12
  transition: var(--transition);
14
13
  cursor: pointer;
@@ -37,7 +36,7 @@
37
36
 
38
37
  &:focus,
39
38
  &:hover {
40
- &.default {
39
+ &.default:not(:disabled) {
41
40
  .icon {
42
41
  color: var(--color--foreground--secondary);
43
42
  }
@@ -54,9 +53,7 @@
54
53
  }
55
54
 
56
55
  &[disabled] {
57
- opacity: var(--opacity--disabled);
58
- box-shadow: none;
59
- cursor: not-allowed;
56
+ @include disabled;
60
57
  }
61
58
  }
62
59
 
@@ -47,6 +47,10 @@
47
47
  margin: 0 auto;
48
48
  }
49
49
 
50
+ .submitInput {
51
+ display: none;
52
+ }
53
+
50
54
  .column {
51
55
  display: flex;
52
56
  flex-direction: column;
@@ -58,6 +62,11 @@
58
62
  }
59
63
  }
60
64
 
65
+ .resultsContainer {
66
+ flex: 1;
67
+ position: relative;
68
+ }
69
+
61
70
  .dictionary {
62
71
  display: flex;
63
72
  flex-direction: column;
@@ -72,11 +81,6 @@
72
81
  flex: 0 0 auto;
73
82
  }
74
83
 
75
- .resultsContainer {
76
- flex: 1;
77
- position: relative;
78
- }
79
-
80
84
  .bottomContainer {
81
85
  flex: 0 0 auto;
82
86
  display: flex;
@@ -101,24 +105,8 @@
101
105
  border: var(--border);
102
106
  }
103
107
 
104
- .submitInput {
105
- display: none;
106
- }
107
-
108
108
  .controls {
109
109
  width: 100%;
110
- display: flex;
111
- align-items: flex-start;
112
- justify-content: center;
113
- gap: var(--spacing--l);
114
- }
115
-
116
- .resultCandidatePicker {
117
- flex: 1;
118
- }
119
-
120
- .apply {
121
- flex: 0 0 auto;
122
110
  }
123
111
 
124
112
  .solve {
@@ -17,14 +17,10 @@ import {
17
17
  } from 'parameters';
18
18
  import {
19
19
  resultsSlice,
20
- selectAreResultsOutdated,
21
20
  selectConfig,
22
21
  selectResultCandidate,
23
- selectSolveError,
24
22
  selectSortedFilteredResults,
25
- selectSortedResults,
26
23
  solveSlice,
27
- useTranslate,
28
24
  useTypedSelector,
29
25
  } from 'state';
30
26
 
@@ -32,11 +28,10 @@ import Board from '../Board';
32
28
  import Dictionary from '../Dictionary';
33
29
  import DictionaryInput from '../DictionaryInput';
34
30
  import Rack from '../Rack';
35
- import ResultCandidatePicker from '../ResultCandidatePicker';
36
31
  import Results from '../Results';
37
32
  import Well from '../Well';
38
33
 
39
- import { ApplyButton, EmptyState, SolveButton } from './components';
34
+ import { MobileControls, SolveButton } from './components';
40
35
  import styles from './Solver.module.scss';
41
36
 
42
37
  interface Props {
@@ -49,20 +44,21 @@ interface Props {
49
44
  // eslint-disable-next-line max-statements
50
45
  const Solver: FunctionComponent<Props> = ({ className, height, width, onShowResults }) => {
51
46
  const dispatch = useDispatch();
52
- const translate = useTranslate();
53
47
  const isTouchDevice = useIsTouchDevice();
54
48
  const [bottomContainerRef, { height: bottomContainerHeight }] = useMeasure<HTMLDivElement>();
55
49
  const [resultsContainerRef, { width: resultsContainerWidth }] = useMeasure<HTMLDivElement>();
56
50
  const isLessThanXl = useMediaQuery('<xl');
57
51
  const isLessThanL = useMediaQuery('<l');
52
+ const isLessThanM = useMediaQuery('<m');
58
53
  const componentsSpacing = isLessThanXl ? COMPONENTS_SPACING_SMALL : COMPONENTS_SPACING;
59
54
  const maxBoardWidth = width - resultsContainerWidth - (isLessThanL ? 0 : componentsSpacing) - 2 * componentsSpacing;
60
- const maxBoardHeight = Math.max(height - bottomContainerHeight, isLessThanL ? 0 : COLUMN_MIN_HEIGHT);
55
+ const maxBoardHeight = Math.max(
56
+ height - bottomContainerHeight,
57
+ isLessThanL ? 0 : COLUMN_MIN_HEIGHT,
58
+ isLessThanM ? Number.POSITIVE_INFINITY : 0,
59
+ );
61
60
  const config = useTypedSelector(selectConfig);
62
61
  const resultCandidate = useTypedSelector(selectResultCandidate);
63
- const isOutdated = useTypedSelector(selectAreResultsOutdated);
64
- const allResults = useTypedSelector(selectSortedResults);
65
- const error = useTypedSelector(selectSolveError);
66
62
  const results = useTypedSelector(selectSortedFilteredResults);
67
63
  const [bestResult] = results || [];
68
64
  const cellWidth = (maxBoardWidth - (config.boardWidth + 1) * BORDER_WIDTH) / config.boardWidth;
@@ -159,43 +155,11 @@ const Solver: FunctionComponent<Props> = ({ className, height, width, onShowResu
159
155
  </form>
160
156
 
161
157
  {isLessThanL && (
162
- <div className={styles.controls} style={{ maxWidth: maxControlsWidth }}>
163
- {typeof error !== 'undefined' && (
164
- <EmptyState variant="error" onClick={onShowResults}>
165
- {error.message}
166
- </EmptyState>
167
- )}
168
-
169
- {typeof error === 'undefined' && typeof results === 'undefined' && (
170
- <EmptyState variant="info" onClick={onShowResults}>
171
- {translate('results.empty-state.uninitialized')}
172
- </EmptyState>
173
- )}
174
-
175
- {typeof error === 'undefined' && typeof results !== 'undefined' && typeof allResults !== 'undefined' && (
176
- <>
177
- {(isOutdated || !resultCandidate) && (
178
- <EmptyState variant="info" onClick={onShowResults}>
179
- {translate('results.empty-state.outdated')}
180
- </EmptyState>
181
- )}
182
-
183
- {!isOutdated && allResults.length === 0 && (
184
- <EmptyState variant="warning" onClick={onShowResults}>
185
- {translate('results.empty-state.no-results')}
186
- </EmptyState>
187
- )}
188
-
189
- {!isOutdated && allResults.length > 0 && resultCandidate && (
190
- <ResultCandidatePicker className={styles.resultCandidatePicker} onClick={onShowResults} />
191
- )}
192
- </>
193
- )}
194
-
195
- {allResults && allResults.length > 0 && !isOutdated && resultCandidate && (
196
- <ApplyButton className={classNames(styles.submit, styles.apply)} />
197
- )}
198
- </div>
158
+ <MobileControls
159
+ className={styles.controls}
160
+ style={{ maxWidth: maxControlsWidth }}
161
+ onShowResults={onShowResults}
162
+ />
199
163
  )}
200
164
  </div>
201
165
  </div>
@@ -0,0 +1,62 @@
1
+ import { FunctionComponent, HTMLProps } from 'react';
2
+
3
+ import {
4
+ selectAreResultsOutdated,
5
+ selectResultCandidate,
6
+ selectSolveError,
7
+ selectSortedResults,
8
+ useTranslate,
9
+ useTypedSelector,
10
+ } from 'state';
11
+
12
+ import EmptyState from '../EmptyState';
13
+ import ResultCandidatePicker from '../ResultCandidatePicker';
14
+
15
+ interface Props extends HTMLProps<HTMLDivElement> {
16
+ onShowResults: () => void;
17
+ }
18
+
19
+ // eslint-disable-next-line max-statements
20
+ const MobileControls: FunctionComponent<Props> = ({ onShowResults, ...props }) => {
21
+ const translate = useTranslate();
22
+ const resultCandidate = useTypedSelector(selectResultCandidate);
23
+ const isOutdated = useTypedSelector(selectAreResultsOutdated);
24
+ const allResults = useTypedSelector(selectSortedResults);
25
+ const error = useTypedSelector(selectSolveError);
26
+
27
+ return (
28
+ <div {...props}>
29
+ {typeof error !== 'undefined' && (
30
+ <EmptyState variant="error" onClick={onShowResults}>
31
+ {error.message}
32
+ </EmptyState>
33
+ )}
34
+
35
+ {typeof error === 'undefined' && typeof allResults === 'undefined' && (
36
+ <EmptyState variant="info" onClick={onShowResults}>
37
+ {translate('results.empty-state.uninitialized')}
38
+ </EmptyState>
39
+ )}
40
+
41
+ {typeof error === 'undefined' && typeof allResults !== 'undefined' && (
42
+ <>
43
+ {(isOutdated || !resultCandidate) && (
44
+ <EmptyState variant="info" onClick={onShowResults}>
45
+ {translate('results.empty-state.outdated')}
46
+ </EmptyState>
47
+ )}
48
+
49
+ {!isOutdated && allResults.length === 0 && (
50
+ <EmptyState variant="warning" onClick={onShowResults}>
51
+ {translate('results.empty-state.no-results')}
52
+ </EmptyState>
53
+ )}
54
+
55
+ {!isOutdated && allResults.length > 0 && resultCandidate && <ResultCandidatePicker onClick={onShowResults} />}
56
+ </>
57
+ )}
58
+ </div>
59
+ );
60
+ };
61
+
62
+ export default MobileControls;
@@ -0,0 +1 @@
1
+ export { default } from './MobileControls';
@@ -1,9 +1,51 @@
1
1
  @import 'styles/mixins';
2
2
 
3
3
  .resultCandidatePicker {
4
+ display: flex;
5
+ align-items: center;
6
+ gap: var(--spacing--l);
7
+ }
8
+
9
+ .buttons {
10
+ flex: 0 0 auto;
11
+ display: flex;
12
+ border-radius: var(--border--radius);
13
+ box-shadow: var(--box-shadow);
14
+
15
+ @include media('<xs') {
16
+ display: none;
17
+ }
18
+ }
19
+
20
+ .button {
21
+ padding: var(--spacing--m);
22
+ box-shadow: none;
23
+
24
+ &:focus-within {
25
+ z-index: 1;
26
+ }
27
+
28
+ &:first-child {
29
+ border-right: none;
30
+ border-top-right-radius: 0;
31
+ border-bottom-right-radius: 0;
32
+ }
33
+
34
+ &:last-child {
35
+ border-top-left-radius: 0;
36
+ border-bottom-left-radius: 0;
37
+ }
38
+
39
+ [dir='rtl'] & {
40
+ transform: rotate(180deg);
41
+ }
42
+ }
43
+
44
+ .resultCandidate {
4
45
  @include button-reset;
5
46
  @include focus-effect;
6
47
 
48
+ flex: 1;
7
49
  display: flex;
8
50
  align-items: center;
9
51
  min-width: 0;
@@ -15,9 +57,7 @@
15
57
  cursor: pointer;
16
58
 
17
59
  &[disabled] {
18
- opacity: var(--opacity--disabled);
19
- box-shadow: none;
20
- cursor: not-allowed;
60
+ @include disabled;
21
61
  }
22
62
  }
23
63
 
@@ -74,3 +114,7 @@
74
114
  height: $size;
75
115
  color: var(--color--inactive);
76
116
  }
117
+
118
+ .apply {
119
+ flex: 0 0 auto;
120
+ }
@@ -0,0 +1,75 @@
1
+ import classNames from 'classnames';
2
+ import { FunctionComponent, HTMLProps } from 'react';
3
+ import { useDispatch } from 'react-redux';
4
+
5
+ import { ChevronDown, ChevronLeft, ChevronRight } from 'icons';
6
+ import {
7
+ resultsSlice,
8
+ selectAreResultsOutdated,
9
+ selectLocale,
10
+ selectResultCandidate,
11
+ selectSortedResults,
12
+ useTypedSelector,
13
+ } from 'state';
14
+
15
+ import Button from '../../../Button';
16
+ import ApplyButton from '../ApplyButton';
17
+
18
+ import styles from './ResultCandidatePicker.module.scss';
19
+
20
+ const ResultCandidatePicker: FunctionComponent<HTMLProps<HTMLDivElement>> = ({ className, ...props }) => {
21
+ const dispatch = useDispatch();
22
+ const locale = useTypedSelector(selectLocale);
23
+ const isOutdated = useTypedSelector(selectAreResultsOutdated);
24
+ const sortedResults = useTypedSelector(selectSortedResults);
25
+ const results = sortedResults || [];
26
+ const resultCandidate = useTypedSelector(selectResultCandidate);
27
+
28
+ if (!resultCandidate) {
29
+ return null;
30
+ }
31
+
32
+ const index = results.findIndex((result) => result.id === resultCandidate.id);
33
+ const isPreviousDisabled = index <= 0;
34
+ const isNextDisabled = index >= results.length - 1;
35
+
36
+ const handleNextClick = () => {
37
+ if (!isNextDisabled) {
38
+ const nextResult = results[index + 1];
39
+ dispatch(resultsSlice.actions.changeResultCandidate(nextResult));
40
+ }
41
+ };
42
+
43
+ const handlePreviousClick = () => {
44
+ if (!isPreviousDisabled) {
45
+ const previousResult = results[index - 1];
46
+ dispatch(resultsSlice.actions.changeResultCandidate(previousResult));
47
+ }
48
+ };
49
+
50
+ return (
51
+ <div className={classNames(styles.resultCandidatePicker, className)} {...props}>
52
+ <div className={styles.buttons}>
53
+ <Button
54
+ className={styles.button}
55
+ disabled={isPreviousDisabled}
56
+ Icon={ChevronLeft}
57
+ onClick={handlePreviousClick}
58
+ />
59
+ <Button className={styles.button} disabled={isNextDisabled} Icon={ChevronRight} onClick={handleNextClick} />
60
+ </div>
61
+
62
+ <button className={styles.resultCandidate} disabled={isOutdated} type="button">
63
+ <div className={styles.points}>{resultCandidate.points.toLocaleString(locale)}</div>
64
+ <div className={styles.word}>{resultCandidate.word}</div>
65
+ <div className={styles.iconContainer}>
66
+ <ChevronDown className={styles.icon} />
67
+ </div>
68
+ </button>
69
+
70
+ <ApplyButton className={styles.apply} />
71
+ </div>
72
+ );
73
+ };
74
+
75
+ export default ResultCandidatePicker;
@@ -1,3 +1,5 @@
1
1
  export { default as ApplyButton } from './ApplyButton';
2
2
  export { default as EmptyState } from './EmptyState';
3
+ export { default as MobileControls } from './MobileControls';
4
+ export { default as ResultCandidatePicker } from './ResultCandidatePicker';
3
5
  export { default as SolveButton } from './SolveButton';
@@ -20,8 +20,7 @@
20
20
  }
21
21
 
22
22
  &[disabled] {
23
- pointer-events: none;
24
- opacity: var(--opacity--disabled);
23
+ @include disabled;
25
24
  }
26
25
  }
27
26
 
@@ -16,7 +16,6 @@ export { default as PlainTiles } from './PlainTiles';
16
16
  export { default as Progress } from './Progress';
17
17
  export { default as Rack } from './Rack';
18
18
  export { default as Radio } from './Radio';
19
- export { default as ResultCandidatePicker } from './ResultCandidatePicker';
20
19
  export { default as Results } from './Results';
21
20
  export { default as ResultsInput } from './ResultsInput';
22
21
  export { default as Sizer } from './Sizer';
@@ -0,0 +1,4 @@
1
+ <!-- https://icons.getbootstrap.com/icons/chevron-left/ -->
2
+ <svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
3
+ <path d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z" fill="currentColor" fill-rule="evenodd" />
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <!-- https://icons.getbootstrap.com/icons/chevron-right/ -->
2
+ <svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
3
+ <path d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" fill="currentColor" fill-rule="evenodd" />
4
+ </svg>