scrabble-solver 2.10.7 → 2.10.8

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 (115) hide show
  1. package/babel.config.js +1 -1
  2. package/lerna.json +1 -1
  3. package/package.json +1 -1
  4. package/packages/configs/package-lock.json +4 -4
  5. package/packages/configs/package.json +3 -3
  6. package/packages/constants/package-lock.json +2 -2
  7. package/packages/constants/package.json +1 -1
  8. package/packages/dictionaries/package-lock.json +2 -2
  9. package/packages/dictionaries/package.json +4 -4
  10. package/packages/logger/package-lock.json +2 -2
  11. package/packages/logger/package.json +1 -1
  12. package/packages/scrabble-solver/.next/BUILD_ID +1 -1
  13. package/packages/scrabble-solver/.next/build-manifest.json +7 -13
  14. package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
  15. package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
  16. package/packages/scrabble-solver/.next/cache/next-server.js.nft.json +1 -1
  17. package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
  18. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
  19. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/0.pack +0 -0
  20. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
  21. package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
  22. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
  23. package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
  24. package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
  25. package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
  26. package/packages/scrabble-solver/.next/server/chunks/176.js +4273 -214
  27. package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
  28. package/packages/scrabble-solver/.next/server/pages/404.html +2 -2
  29. package/packages/scrabble-solver/.next/server/pages/404.js.nft.json +1 -1
  30. package/packages/scrabble-solver/.next/server/pages/500.html +2 -2
  31. package/packages/scrabble-solver/.next/server/pages/_app.js +296 -13
  32. package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
  33. package/packages/scrabble-solver/.next/server/pages/_document.js.nft.json +1 -1
  34. package/packages/scrabble-solver/.next/server/pages/api/solve.js +17 -0
  35. package/packages/scrabble-solver/.next/server/pages/index.html +1 -9
  36. package/packages/scrabble-solver/.next/server/pages/index.js +23 -16
  37. package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
  38. package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
  39. package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -1
  40. package/packages/scrabble-solver/.next/static/Cs23uxWG6AxS72F2yrjHu/_buildManifest.js +1 -0
  41. package/packages/scrabble-solver/.next/static/chunks/pages/{404-67383848027ec49b.js → 404-8cab6d62fe4ead73.js} +1 -1
  42. package/packages/scrabble-solver/.next/static/chunks/pages/_app-dcbbb823dc93a031.js +28 -0
  43. package/packages/scrabble-solver/.next/static/chunks/pages/index-df1ff01aa82d2d4d.js +1 -0
  44. package/packages/scrabble-solver/.next/static/css/bf2e969b88c4e3dd.css +2 -0
  45. package/packages/scrabble-solver/.next/static/css/d1cc6b79b211b7b8.css +1 -0
  46. package/packages/scrabble-solver/.next/trace +55 -55
  47. package/packages/scrabble-solver/package-lock.json +22 -2
  48. package/packages/scrabble-solver/package.json +9 -8
  49. package/packages/scrabble-solver/src/components/Badge/Badge.module.scss +1 -1
  50. package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.module.scss +32 -64
  51. package/packages/scrabble-solver/src/components/Board/components/Cell/CellPure.tsx +15 -22
  52. package/packages/scrabble-solver/src/components/Button/Button.module.scss +2 -2
  53. package/packages/scrabble-solver/src/components/Checkbox/Checkbox.tsx +1 -4
  54. package/packages/scrabble-solver/src/components/Dictionary/Dictionary.tsx +28 -30
  55. package/packages/scrabble-solver/src/components/DictionaryInput/DictionaryInput.tsx +3 -0
  56. package/packages/scrabble-solver/src/components/Key/Key.module.scss +1 -1
  57. package/packages/scrabble-solver/src/components/LogoSplashScreen/LogoSplashScreen.module.scss +1 -1
  58. package/packages/scrabble-solver/src/components/Modal/Modal.module.scss +4 -2
  59. package/packages/scrabble-solver/src/components/Rack/Rack.module.scss +4 -0
  60. package/packages/scrabble-solver/src/components/Radio/Radio.tsx +1 -4
  61. package/packages/scrabble-solver/src/components/Results/Results.module.scss +2 -2
  62. package/packages/scrabble-solver/src/components/SeoMessage/SeoMessage.tsx +19 -0
  63. package/packages/scrabble-solver/src/components/SeoMessage/index.ts +1 -0
  64. package/packages/scrabble-solver/src/components/Solver/components/EmptyState/EmptyState.module.scss +1 -1
  65. package/packages/scrabble-solver/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.module.scss +9 -2
  66. package/packages/scrabble-solver/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +2 -1
  67. package/packages/scrabble-solver/src/components/Tile/Tile.module.scss +49 -11
  68. package/packages/scrabble-solver/src/components/Tile/Tile.tsx +23 -8
  69. package/packages/scrabble-solver/src/components/Tile/TilePure.tsx +27 -20
  70. package/packages/scrabble-solver/src/components/Tooltip/Tooltip.module.scss +7 -7
  71. package/packages/scrabble-solver/src/components/index.ts +1 -0
  72. package/packages/scrabble-solver/src/i18n/de.json +1 -0
  73. package/packages/scrabble-solver/src/i18n/en.json +1 -0
  74. package/packages/scrabble-solver/src/i18n/es.json +1 -0
  75. package/packages/scrabble-solver/src/i18n/fa.json +1 -0
  76. package/packages/scrabble-solver/src/i18n/fr.json +1 -0
  77. package/packages/scrabble-solver/src/i18n/pl.json +1 -0
  78. package/packages/scrabble-solver/src/icons/Flag.svg +2 -2
  79. package/packages/scrabble-solver/src/icons/FlagFill.svg +4 -0
  80. package/packages/scrabble-solver/src/icons/Square.svg +4 -0
  81. package/packages/scrabble-solver/src/icons/SquareFill.svg +4 -0
  82. package/packages/scrabble-solver/src/icons/index.ts +3 -0
  83. package/packages/scrabble-solver/src/modals/RemainingTilesModal/components/Character/Character.module.scss +1 -1
  84. package/packages/scrabble-solver/src/modals/ResultsModal/ResultsModal.module.scss +1 -1
  85. package/packages/scrabble-solver/src/modals/SettingsModal/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +1 -2
  86. package/packages/scrabble-solver/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.tsx +1 -2
  87. package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.module.scss +14 -24
  88. package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.tsx +1 -2
  89. package/packages/scrabble-solver/src/pages/_app.tsx +9 -5
  90. package/packages/scrabble-solver/src/pages/index.module.scss +1 -2
  91. package/packages/scrabble-solver/src/pages/index.tsx +10 -8
  92. package/packages/scrabble-solver/src/parameters/index.ts +10 -0
  93. package/packages/scrabble-solver/src/state/slices/boardSlice.ts +5 -5
  94. package/packages/scrabble-solver/src/styles/mixins.scss +4 -2
  95. package/packages/scrabble-solver/src/styles/variables.scss +39 -32
  96. package/packages/scrabble-solver/src/types/index.ts +1 -0
  97. package/packages/solver/package-lock.json +2 -2
  98. package/packages/solver/package.json +5 -5
  99. package/packages/types/package-lock.json +3 -3
  100. package/packages/types/package.json +2 -2
  101. package/packages/word-definitions/package-lock.json +2 -2
  102. package/packages/word-definitions/package.json +2 -2
  103. package/packages/word-lists/package-lock.json +2 -2
  104. package/packages/word-lists/package.json +2 -2
  105. package/packages/scrabble-solver/.next/server/chunks/579.js +0 -3925
  106. package/packages/scrabble-solver/.next/static/6RggBFm8kHrh-k1-CG3um/_buildManifest.js +0 -1
  107. package/packages/scrabble-solver/.next/static/chunks/490-d29992f1c264d70e.js +0 -5
  108. package/packages/scrabble-solver/.next/static/chunks/509-6ad4482d4351452c.js +0 -1
  109. package/packages/scrabble-solver/.next/static/chunks/pages/_app-c58cfa832b76cc87.js +0 -24
  110. package/packages/scrabble-solver/.next/static/chunks/pages/index-146039f501e49c08.js +0 -1
  111. package/packages/scrabble-solver/.next/static/css/4482c4a0064d3807.css +0 -1
  112. package/packages/scrabble-solver/.next/static/css/78e42ad01f580f64.css +0 -1
  113. package/packages/scrabble-solver/.next/static/css/9d1013ec684361b9.css +0 -1
  114. package/packages/scrabble-solver/src/components/Board/components/Cell/Button.tsx +0 -32
  115. /package/packages/scrabble-solver/.next/static/{6RggBFm8kHrh-k1-CG3um → Cs23uxWG6AxS72F2yrjHu}/_ssgManifest.js +0 -0
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@scrabble-solver/scrabble-solver",
3
- "version": "2.10.7",
3
+ "version": "2.10.8",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/scrabble-solver",
9
- "version": "2.10.7",
9
+ "version": "2.10.8",
10
10
  "license": "CC BY-NC-ND 4.0",
11
11
  "dependencies": {
12
12
  "@kamilmielnik/trie": "^2.0.1",
@@ -15,6 +15,7 @@
15
15
  "classnames": "^2.3.2",
16
16
  "include-media": "^2.0.0",
17
17
  "include-media-query-builder": "^1.1.0",
18
+ "merge-refs": "^1.1.2",
18
19
  "next": "^13.1.6",
19
20
  "normalize.css": "^8.0.1",
20
21
  "react": "^18.2.0",
@@ -4805,6 +4806,17 @@
4805
4806
  "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
4806
4807
  "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
4807
4808
  },
4809
+ "node_modules/merge-refs": {
4810
+ "version": "1.1.2",
4811
+ "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.1.2.tgz",
4812
+ "integrity": "sha512-t+FvJw2LXHnNTMRmNB2HY04uVdvCW8AbfwZi0DgUxFEoP20rnvXxZmePRML1nDiLO5KKE0p4GDu1qHhrig/Jpg==",
4813
+ "dependencies": {
4814
+ "@types/react": "*"
4815
+ },
4816
+ "funding": {
4817
+ "url": "https://github.com/wojtekmaj/merge-refs?sponsor=1"
4818
+ }
4819
+ },
4808
4820
  "node_modules/merge-stream": {
4809
4821
  "version": "2.0.0",
4810
4822
  "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -10177,6 +10189,14 @@
10177
10189
  "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
10178
10190
  "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
10179
10191
  },
10192
+ "merge-refs": {
10193
+ "version": "1.1.2",
10194
+ "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.1.2.tgz",
10195
+ "integrity": "sha512-t+FvJw2LXHnNTMRmNB2HY04uVdvCW8AbfwZi0DgUxFEoP20rnvXxZmePRML1nDiLO5KKE0p4GDu1qHhrig/Jpg==",
10196
+ "requires": {
10197
+ "@types/react": "*"
10198
+ }
10199
+ },
10180
10200
  "merge-stream": {
10181
10201
  "version": "2.0.0",
10182
10202
  "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/scrabble-solver",
3
- "version": "2.10.7",
3
+ "version": "2.10.8",
4
4
  "description": "Scrabble Solver 2 - App",
5
5
  "engines": {
6
6
  "node": ">=16"
@@ -31,16 +31,17 @@
31
31
  "@kamilmielnik/trie": "^2.0.1",
32
32
  "@popperjs/core": "^2.11.6",
33
33
  "@reduxjs/toolkit": "^1.9.3",
34
- "@scrabble-solver/configs": "^2.10.7",
35
- "@scrabble-solver/constants": "^2.10.7",
36
- "@scrabble-solver/dictionaries": "^2.10.7",
37
- "@scrabble-solver/logger": "^2.10.7",
38
- "@scrabble-solver/solver": "^2.10.7",
39
- "@scrabble-solver/types": "^2.10.7",
40
- "@scrabble-solver/word-definitions": "^2.10.7",
34
+ "@scrabble-solver/configs": "^2.10.8",
35
+ "@scrabble-solver/constants": "^2.10.8",
36
+ "@scrabble-solver/dictionaries": "^2.10.8",
37
+ "@scrabble-solver/logger": "^2.10.8",
38
+ "@scrabble-solver/solver": "^2.10.8",
39
+ "@scrabble-solver/types": "^2.10.8",
40
+ "@scrabble-solver/word-definitions": "^2.10.8",
41
41
  "classnames": "^2.3.2",
42
42
  "include-media": "^2.0.0",
43
43
  "include-media-query-builder": "^1.1.0",
44
+ "merge-refs": "^1.1.2",
44
45
  "next": "^13.1.6",
45
46
  "normalize.css": "^8.0.1",
46
47
  "react": "^18.2.0",
@@ -5,7 +5,7 @@
5
5
  padding: var(--spacing--xs) var(--spacing--m);
6
6
  border: var(--border);
7
7
  border-radius: var(--border--radius);
8
- background-color: var(--color--background--overlay);
8
+ background-color: var(--color--background--element);
9
9
  line-height: var(--line-height);
10
10
  font-size: var(--font--size--m);
11
11
  font-weight: bold;
@@ -1,13 +1,11 @@
1
1
  @import 'styles/mixins';
2
2
 
3
- $icon-size: 16px;
4
-
5
3
  .cell {
6
4
  @include focus-effect;
7
5
 
8
6
  position: relative;
9
7
  display: table-cell;
10
- background-color: white;
8
+ background-color: var(--color--white);
11
9
  border-bottom: var(--border--width) dotted var(--border--color--light);
12
10
  transition: var(--transition);
13
11
  background-clip: padding-box;
@@ -36,57 +34,57 @@ $icon-size: 16px;
36
34
 
37
35
  &.bonusStart {
38
36
  &::before {
39
- background-color: var(--color--violet--light);
37
+ background-color: var(--color--bonus--start);
40
38
  }
41
39
  }
42
40
 
43
41
  &.bonusCharacter1 {
44
42
  &::before {
45
- background-color: var(--color--yellow--light);
43
+ background-color: var(--color--bonus--character--1);
46
44
  }
47
45
  }
48
46
 
49
47
  &.bonusCharacter2 {
50
48
  &::before {
51
- background-color: var(--color--green--light);
49
+ background-color: var(--color--bonus--character--2);
52
50
  }
53
51
  }
54
52
 
55
53
  &.bonusCharacter3 {
56
54
  &::before {
57
- background-color: var(--color--blue--light);
55
+ background-color: var(--color--bonus--character--3);
58
56
  }
59
57
  }
60
58
 
61
59
  &.bonusCharacter5 {
62
60
  &::before {
63
- background-color: var(--color--red--light);
61
+ background-color: var(--color--bonus--character--5);
64
62
  }
65
63
  }
66
64
 
67
65
  &.bonusCharacterMultiplier2 {
68
66
  &::before {
69
- background-color: var(--color--light-blue--light);
67
+ background-color: var(--color--bonus--character-multiplier--2);
70
68
  }
71
69
  }
72
70
 
73
71
  &.bonusCharacterMultiplier3 {
74
72
  &::before {
75
- background-color: var(--color--dark-blue--light);
73
+ background-color: var(--color--bonus--character-multiplier--3);
76
74
  }
77
75
  }
78
76
 
79
77
  &.bonusWord2 {
80
78
  &::before {
81
79
  content: 'x2';
82
- background-color: var(--color--orange);
80
+ background-color: var(--color--bonus--word-multiplier--2);
83
81
  }
84
82
  }
85
83
 
86
84
  &.bonusWord3 {
87
85
  &::before {
88
86
  content: 'x3';
89
- background-color: var(--color--pink);
87
+ background-color: var(--color--bonus--word-multiplier--3);
90
88
  }
91
89
  }
92
90
 
@@ -112,7 +110,7 @@ $icon-size: 16px;
112
110
  pointer-events: none;
113
111
  font-size: 60%;
114
112
  font-weight: bold;
115
- color: white;
113
+ color: var(--color--white);
116
114
  content: ' ';
117
115
 
118
116
  [lang='fa-IR'] & {
@@ -121,7 +119,7 @@ $icon-size: 16px;
121
119
  }
122
120
 
123
121
  &:focus-within {
124
- z-index: 1;
122
+ z-index: 2;
125
123
 
126
124
  .actions {
127
125
  display: flex;
@@ -135,9 +133,15 @@ $icon-size: 16px;
135
133
  }
136
134
 
137
135
  .actions {
136
+ --offset: var(--spacing--m);
137
+
138
+ @include media('<xs') {
139
+ --offset: var(--spacing--s);
140
+ }
141
+
138
142
  display: none;
139
143
  position: absolute;
140
- top: -$icon-size;
144
+ bottom: calc(100% - var(--offset));
141
145
  z-index: 2;
142
146
  transition: var(--transition);
143
147
  pointer-events: none;
@@ -145,30 +149,17 @@ $icon-size: 16px;
145
149
  border-radius: var(--border--radius);
146
150
 
147
151
  [dir='ltr'] & {
148
- left: calc(100% + var(--spacing--s) - #{$icon-size});
152
+ left: calc(100% - var(--offset));
149
153
  }
150
154
 
151
155
  [dir='rtl'] & {
152
- right: calc(100% + var(--spacing--s) - #{$icon-size});
156
+ right: calc(100% - var(--offset));
153
157
  }
154
158
  }
155
159
 
156
160
  .action {
157
- @include button-reset;
158
-
159
- display: flex;
160
- justify-content: center;
161
- padding: var(--spacing--s);
162
- user-select: none;
163
- pointer-events: none;
164
- box-sizing: content-box;
165
- background-color: white;
166
- border: var(--border);
167
- font-size: var(--font--size--m);
168
- line-height: $icon-size;
169
- color: var(--color--foreground--secondary);
170
- transition: var(--transition);
171
- cursor: pointer;
161
+ padding: var(--spacing--m);
162
+ box-shadow: none !important;
172
163
 
173
164
  & + & {
174
165
  [dir='ltr'] & {
@@ -182,35 +173,28 @@ $icon-size: 16px;
182
173
 
183
174
  [dir='ltr'] & {
184
175
  &:first-child {
185
- border-top-left-radius: var(--border--radius);
186
- border-bottom-left-radius: var(--border--radius);
176
+ border-top-right-radius: 0;
177
+ border-bottom-right-radius: 0;
187
178
  }
188
179
 
189
180
  &:last-child {
190
- border-top-right-radius: var(--border--radius);
191
- border-bottom-right-radius: var(--border--radius);
181
+ border-top-left-radius: 0;
182
+ border-bottom-left-radius: 0;
192
183
  }
193
184
  }
194
185
 
195
186
  [dir='rtl'] & {
196
187
  &:first-child {
197
- border-top-right-radius: var(--border--radius);
198
- border-bottom-right-radius: var(--border--radius);
188
+ border-top-left-radius: 0;
189
+ border-bottom-left-radius: 0;
199
190
  }
200
191
 
201
192
  &:last-child {
202
- border-top-left-radius: var(--border--radius);
203
- border-bottom-left-radius: var(--border--radius);
193
+ border-top-right-radius: 0;
194
+ border-bottom-right-radius: 0;
204
195
  }
205
196
  }
206
197
 
207
- &,
208
- .filterCell,
209
- .toggleDirection {
210
- width: $icon-size;
211
- height: $icon-size;
212
- }
213
-
214
198
  &:active,
215
199
  &:hover {
216
200
  color: var(--color--foreground);
@@ -229,22 +213,6 @@ $icon-size: 16px;
229
213
  }
230
214
  }
231
215
 
232
- .blank {
233
- user-select: none;
234
-
235
- &.active {
236
- font-weight: bold;
237
- }
238
- }
239
-
240
- .filterCell {
241
- color: var(--color--inactive);
242
-
243
- &.filtered {
244
- color: var(--color--foreground--secondary);
245
- }
246
- }
247
-
248
216
  .iconContainer {
249
217
  position: absolute;
250
218
  top: 0;
@@ -262,7 +230,7 @@ $icon-size: 16px;
262
230
 
263
231
  .flag,
264
232
  .star {
265
- color: white;
233
+ color: var(--color--white);
266
234
  }
267
235
 
268
236
  .star {
@@ -10,12 +10,12 @@ import {
10
10
  RefObject,
11
11
  } from 'react';
12
12
 
13
- import { ArrowDown, Flag, Star } from 'icons';
13
+ import { ArrowDown, Flag, FlagFill, Square, SquareFill, Star } from 'icons';
14
14
  import { Translate } from 'types';
15
15
 
16
+ import Button from '../../../Button';
16
17
  import Tile from '../../../Tile';
17
18
 
18
- import Button from './Button';
19
19
  import styles from './Cell.module.scss';
20
20
  import { getBonusClassname } from './lib';
21
21
 
@@ -84,7 +84,7 @@ const CellPure: FunctionComponent<Props> = ({
84
84
 
85
85
  {isFiltered && (
86
86
  <div className={classNames(styles.iconContainer, styles.flagContainer)}>
87
- <Flag className={styles.flag} />
87
+ <FlagFill className={styles.flag} />
88
88
  </div>
89
89
  )}
90
90
 
@@ -108,40 +108,33 @@ const CellPure: FunctionComponent<Props> = ({
108
108
  <div className={styles.actions}>
109
109
  <Button
110
110
  aria-label={translate('cell.toggle-direction')}
111
+ className={styles.action}
112
+ Icon={ArrowDown}
113
+ iconClassName={classNames(styles.toggleDirection, {
114
+ [styles.right]: direction === 'horizontal',
115
+ })}
111
116
  tooltip={translate('cell.toggle-direction')}
112
117
  onClick={onDirectionToggleClick}
113
- >
114
- <ArrowDown
115
- className={classNames(styles.toggleDirection, {
116
- [styles.right]: direction === 'horizontal',
117
- })}
118
- />
119
- </Button>
118
+ />
120
119
 
121
120
  {isEmpty && (
122
121
  <Button
123
122
  aria-label={translate('cell.filter-cell')}
124
- className={classNames(styles.filterCell, {
125
- [styles.filtered]: isFiltered,
126
- })}
123
+ className={classNames(styles.action)}
124
+ Icon={isFiltered ? Flag : FlagFill}
127
125
  tooltip={translate('cell.filter-cell')}
128
126
  onClick={onToggleFilterCellClick}
129
- >
130
- <Flag />
131
- </Button>
127
+ />
132
128
  )}
133
129
 
134
130
  {!isEmpty && (
135
131
  <Button
136
132
  aria-label={tile.isBlank ? translate('cell.set-not-blank') : translate('cell.set-blank')}
137
- className={classNames(styles.blank, {
138
- [styles.active]: tile.isBlank,
139
- })}
133
+ className={styles.action}
134
+ Icon={tile.isBlank ? SquareFill : Square}
140
135
  tooltip={tile.isBlank ? translate('cell.set-not-blank') : translate('cell.set-blank')}
141
136
  onClick={onToggleBlankClick}
142
- >
143
- B
144
- </Button>
137
+ />
145
138
  )}
146
139
  </div>
147
140
  )}
@@ -21,11 +21,11 @@
21
21
 
22
22
  &.primary {
23
23
  background-color: var(--color--primary);
24
- color: white;
24
+ color: var(--color--primary--opposite);
25
25
  }
26
26
 
27
27
  &.default {
28
- background-color: var(--color--background--overlay);
28
+ background-color: var(--color--background--element);
29
29
  color: var(--color--foreground);
30
30
 
31
31
  .icon {
@@ -10,23 +10,20 @@ interface Props {
10
10
  children?: ReactNode;
11
11
  className?: string;
12
12
  disabled?: boolean;
13
- id: string;
14
13
  name: string;
15
14
  onChange: ChangeEventHandler<HTMLInputElement>;
16
15
  }
17
16
 
18
- const Checkbox: FunctionComponent<Props> = ({ checked, children, className, disabled, id, name, onChange }) => (
17
+ const Checkbox: FunctionComponent<Props> = ({ checked, children, className, disabled, name, onChange }) => (
19
18
  <label
20
19
  className={classNames(styles.checkbox, className, {
21
20
  [styles.checked]: checked,
22
21
  })}
23
- htmlFor={id}
24
22
  >
25
23
  <input
26
24
  checked={checked}
27
25
  className={styles.input}
28
26
  disabled={disabled}
29
- id={id}
30
27
  name={name}
31
28
  type="checkbox"
32
29
  onChange={onChange}
@@ -27,6 +27,10 @@ const Dictionary: FunctionComponent<Props> = ({ className }) => {
27
27
  >
28
28
  {typeof error !== 'undefined' && <EmptyState variant="error">{error.message}</EmptyState>}
29
29
 
30
+ {results.length === 0 && (
31
+ <EmptyState variant="info">{translate('dictionary.empty-state.uninitialized')}</EmptyState>
32
+ )}
33
+
30
34
  {results.map(({ definitions, exists, isAllowed, word }) => (
31
35
  <div
32
36
  className={classNames(styles.result, {
@@ -35,40 +39,34 @@ const Dictionary: FunctionComponent<Props> = ({ className }) => {
35
39
  })}
36
40
  key={word}
37
41
  >
38
- {typeof word === 'undefined' && (
39
- <EmptyState variant="info">{translate('dictionary.empty-state.uninitialized')}</EmptyState>
40
- )}
41
-
42
- {typeof word !== 'undefined' && (
43
- <div className={styles.content}>
44
- {word && <h2 className={styles.word}>{word}</h2>}
42
+ <div className={styles.content}>
43
+ {word && <h2 className={styles.word}>{word}</h2>}
45
44
 
46
- {isAllowed === false && <div>{translate('dictionary.empty-state.not-allowed')}</div>}
45
+ {isAllowed === false && <div>{translate('dictionary.empty-state.not-allowed')}</div>}
47
46
 
48
- {isAllowed === true && (
49
- <>
50
- {definitions.length === 0 && (
51
- <>
52
- {exists && <div>{translate('dictionary.empty-state.no-definitions')}</div>}
53
- {!exists && <div>{translate('dictionary.empty-state.no-results')}</div>}
54
- </>
55
- )}
47
+ {isAllowed === true && (
48
+ <>
49
+ {definitions.length === 0 && (
50
+ <>
51
+ {exists && <div>{translate('dictionary.empty-state.no-definitions')}</div>}
52
+ {!exists && <div>{translate('dictionary.empty-state.no-results')}</div>}
53
+ </>
54
+ )}
56
55
 
57
- {definitions.length > 0 && (
58
- <ul className={styles.definitions}>
59
- {definitions.map((result, index) => (
60
- <li key={index} className={styles.definition}>
61
- {result}
62
- </li>
63
- ))}
64
- </ul>
65
- )}
66
- </>
67
- )}
56
+ {definitions.length > 0 && (
57
+ <ul className={styles.definitions}>
58
+ {definitions.map((result, index) => (
59
+ <li key={index} className={styles.definition}>
60
+ {result}
61
+ </li>
62
+ ))}
63
+ </ul>
64
+ )}
65
+ </>
66
+ )}
68
67
 
69
- {!isLoading && isAllowed === null && <div>{translate('dictionary.empty-state.no-results')}</div>}
70
- </div>
71
- )}
68
+ {!isLoading && isAllowed === null && <div>{translate('dictionary.empty-state.no-results')}</div>}
69
+ </div>
72
70
  </div>
73
71
  ))}
74
72
 
@@ -1,3 +1,4 @@
1
+ import { COMMA_ARABIC, COMMA_LATIN } from '@scrabble-solver/constants';
1
2
  import classNames from 'classnames';
2
3
  import { ChangeEvent, FormEvent, FunctionComponent } from 'react';
3
4
  import { useDispatch } from 'react-redux';
@@ -28,8 +29,10 @@ const DictionaryInput: FunctionComponent<Props> = ({ className }) => {
28
29
  <form className={classNames(styles.dictionaryInput, className)} onSubmit={handleSubmit}>
29
30
  <input
30
31
  className={styles.input}
32
+ pattern={`.*[^\\s${COMMA_ARABIC}${COMMA_LATIN}].*`}
31
33
  placeholder={translate('dictionary.input.placeholder')}
32
34
  required
35
+ title={translate('dictionary.input.title')}
33
36
  type="text"
34
37
  value={input}
35
38
  onChange={handleChange}
@@ -8,7 +8,7 @@ $icon-size: 15px;
8
8
  min-width: $key-size;
9
9
  height: $key-size;
10
10
  padding: var(--spacing--s) var(--spacing--m);
11
- background-color: white;
11
+ background-color: var(--color--white);
12
12
  border: var(--border);
13
13
  border-radius: var(--border--radius);
14
14
  box-shadow: var(--box-shadow);
@@ -43,7 +43,7 @@ $hiding-duration: 200ms;
43
43
 
44
44
  .logoGrayscale {
45
45
  filter: grayscale(1);
46
- opacity: 0.3;
46
+ opacity: var(--opacity--disabled);
47
47
  }
48
48
 
49
49
  .logoColor {
@@ -60,12 +60,14 @@
60
60
  }
61
61
 
62
62
  .container {
63
+ --box-shadow--offset: 1px;
64
+ --box-shadow--offset--negative: calc(-1 * var(--box-shadow--offset));
65
+
63
66
  display: flex;
64
67
  flex-direction: column;
65
68
  height: 100%;
66
69
  background-color: var(--color--background);
67
- transition: var(--transition);
68
- transition-duration: var(--transition--duration--long);
70
+ transition: var(--transition--long);
69
71
  transform: translateX(var(--modal--width));
70
72
  opacity: 0;
71
73
 
@@ -9,4 +9,8 @@
9
9
  @include focus-effect;
10
10
 
11
11
  --background-color: var(--color--background);
12
+
13
+ &:focus-within {
14
+ z-index: 1;
15
+ }
12
16
  }
@@ -8,24 +8,21 @@ interface Props {
8
8
  children?: ReactNode;
9
9
  className?: string;
10
10
  disabled?: boolean;
11
- id: string;
12
11
  name: string;
13
12
  value: string;
14
13
  onChange: ChangeEventHandler<HTMLInputElement>;
15
14
  }
16
15
 
17
- const Radio: FunctionComponent<Props> = ({ checked, children, className, disabled, id, name, value, onChange }) => (
16
+ const Radio: FunctionComponent<Props> = ({ checked, children, className, disabled, name, value, onChange }) => (
18
17
  <label
19
18
  className={classNames(styles.radio, className, {
20
19
  [styles.checked]: checked,
21
20
  })}
22
- htmlFor={id}
23
21
  >
24
22
  <input
25
23
  checked={checked}
26
24
  className={styles.input}
27
25
  disabled={disabled}
28
- id={id}
29
26
  name={name}
30
27
  type="radio"
31
28
  value={value}
@@ -45,7 +45,7 @@ $row-padding-horizontal: calc(var(--spacing--m) + var(--spacing--s));
45
45
  &:focus,
46
46
  &:hover {
47
47
  background-color: var(--color--primary);
48
- color: white;
48
+ color: var(--color--primary--opposite);
49
49
  }
50
50
  }
51
51
 
@@ -73,7 +73,7 @@ $row-padding-horizontal: calc(var(--spacing--m) + var(--spacing--s));
73
73
  &.highlighted {
74
74
  &:not(:disabled) {
75
75
  background-color: var(--color--primary);
76
- color: white;
76
+ color: var(--color--primary--opposite);
77
77
  }
78
78
  }
79
79
  }
@@ -0,0 +1,19 @@
1
+ import { CSSProperties, FunctionComponent } from 'react';
2
+
3
+ const INVISIBLE_STYLE: CSSProperties = {
4
+ color: 'transparent',
5
+ pointerEvents: 'none',
6
+ position: 'absolute',
7
+ userSelect: 'none',
8
+ transform: 'translateY(-9999px)',
9
+ };
10
+
11
+ const SeoMessage: FunctionComponent = () => (
12
+ <p style={INVISIBLE_STYLE}>
13
+ Scrabble Solver 2 is a free and open-source analysis tool for Scrabble and Literaki. Quickly find top scoring words
14
+ using given letters and board state. Available in English, French, German, Polish & Spanish. Source code is
15
+ available on GitHub - contributions are welcome!
16
+ </p>
17
+ );
18
+
19
+ export default SeoMessage;
@@ -0,0 +1 @@
1
+ export { default } from './SeoMessage';
@@ -4,7 +4,7 @@
4
4
  width: 100%;
5
5
  border: var(--border);
6
6
  border-radius: var(--border--radius);
7
- background-color: white;
7
+ background-color: var(--color--white);
8
8
  text-align: center;
9
9
  }
10
10