@scrabble-solver/scrabble-solver 2.18.1 → 2.18.2

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 (194) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +14 -14
  3. package/.next/cache/.previewinfo +1 -1
  4. package/.next/cache/.rscinfo +1 -1
  5. package/.next/cache/.tsbuildinfo +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/client-production/index.pack.old +0 -0
  9. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  10. package/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
  11. package/.next/cache/webpack/server-production/0.pack +0 -0
  12. package/.next/cache/webpack/server-production/index.pack +0 -0
  13. package/.next/cache/webpack/server-production/index.pack.old +0 -0
  14. package/.next/diagnostics/framework.json +1 -1
  15. package/.next/dynamic-css-manifest.json +2 -2
  16. package/.next/prerender-manifest.json +4 -4
  17. package/.next/react-loadable-manifest.json +37 -37
  18. package/.next/routes-manifest.json +1 -1
  19. package/.next/server/chunks/309.js +1 -1
  20. package/.next/server/chunks/344.js +1 -1
  21. package/.next/server/chunks/371.js +1 -1
  22. package/.next/server/chunks/392.js +1 -1
  23. package/.next/server/chunks/465.js +1 -1
  24. package/.next/server/chunks/546.js +1 -1
  25. package/.next/server/chunks/641.js +1 -1
  26. package/.next/server/chunks/67.js +1 -0
  27. package/.next/server/chunks/712.js +1 -1
  28. package/.next/server/chunks/846.js +1 -1
  29. package/.next/server/chunks/886.js +1 -1
  30. package/.next/server/chunks/942.js +1 -0
  31. package/.next/server/chunks/953.js +1 -1
  32. package/.next/server/chunks/961.js +1 -1
  33. package/.next/server/dynamic-css-manifest.js +1 -1
  34. package/.next/server/middleware-build-manifest.js +1 -1
  35. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  36. package/.next/server/pages/404.html +2 -2
  37. package/.next/server/pages/500.html +2 -2
  38. package/.next/server/pages/_app.js +1 -1
  39. package/.next/server/pages/_app.js.nft.json +1 -1
  40. package/.next/server/pages/_document.js +2 -2
  41. package/.next/server/pages/_document.js.nft.json +1 -1
  42. package/.next/server/pages/_error.js +1 -1
  43. package/.next/server/pages/_error.js.nft.json +1 -1
  44. package/.next/server/pages/api/dictionary/[locale]/[word].js +1 -1
  45. package/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
  46. package/.next/server/pages/api/dictionary/[locale].js +1 -1
  47. package/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
  48. package/.next/server/pages/api/solve.js +1 -1
  49. package/.next/server/pages/api/solve.js.nft.json +1 -1
  50. package/.next/server/pages/api/verify.js +1 -1
  51. package/.next/server/pages/api/verify.js.nft.json +1 -1
  52. package/.next/server/pages/index.html +2 -2
  53. package/.next/server/pages/index.js +4 -4
  54. package/.next/server/pages/index.js.nft.json +1 -1
  55. package/.next/server/pages/index.json +1 -1
  56. package/.next/server/pages/not-found.html +2 -2
  57. package/.next/server/pages/not-found.js.nft.json +1 -1
  58. package/.next/server/pages-manifest.json +1 -1
  59. package/.next/static/chunks/100.305bdf9c75b1758f.js +1 -0
  60. package/.next/static/chunks/256.66ff9fb6d7db9ec7.js +1 -0
  61. package/.next/static/chunks/{307.67f52f13e3d60d4e.js → 307.89e6100f58443679.js} +1 -1
  62. package/.next/static/chunks/{363.01eed3233f92b6a4.js → 363.cec65b1f9668a75e.js} +1 -1
  63. package/.next/static/chunks/{422.1559ae6756912ca5.js → 422.3e55b4c94e328701.js} +1 -1
  64. package/.next/static/chunks/{663.d2c9ca36b26695b8.js → 663.bd2c45413fbca518.js} +1 -1
  65. package/.next/static/chunks/693.677c88e0eb1340b5.js +1 -0
  66. package/.next/static/chunks/{820.97b82f751ca49579.js → 820.823e9e885ebb66af.js} +1 -1
  67. package/.next/static/chunks/827.c81b92b383a748c9.js +1 -0
  68. package/.next/static/chunks/{865.a9b563a45848a83c.js → 865.59baba8296c9b116.js} +1 -1
  69. package/.next/static/chunks/912.077603e4f0bc6cca.js +1 -0
  70. package/.next/static/chunks/{939.19b33a3d3c351d73.js → 939.2ad86b50405c7897.js} +1 -1
  71. package/.next/static/chunks/980.7ce17464fc56648a.js +1 -0
  72. package/.next/static/chunks/{main-b92e08f3fc96dd8d.js → main-7e52da35a4beea0b.js} +1 -1
  73. package/.next/static/chunks/pages/_app-f9ec81278ffa7b1a.js +1 -0
  74. package/.next/static/chunks/pages/index-b5bf018100015277.js +1 -0
  75. package/.next/static/chunks/webpack-9f5c9d275348829b.js +1 -0
  76. package/.next/static/css/65bcc9440e067113.css +1 -0
  77. package/.next/static/css/{4dbcacc1122ac6b9.css → 92f85ce358a0a468.css} +1 -1
  78. package/.next/static/css/a691348b788f8bc0.css +1 -0
  79. package/.next/static/css/cd4d7f2458487399.css +1 -0
  80. package/.next/static/{5KOWzYqfY1Z2rjrzptr8D → nvGZh1gPuX98L07YmxlYD}/_buildManifest.js +1 -1
  81. package/.next/trace +21 -21
  82. package/.next/trace-build +1 -1
  83. package/AGENTS.md +9 -0
  84. package/CLAUDE.md +1 -0
  85. package/package.json +14 -12
  86. package/src/components/Board/Board.tsx +3 -1
  87. package/src/components/Board/BoardPure.tsx +26 -20
  88. package/src/components/Board/components/Cell/Cell.tsx +4 -4
  89. package/src/components/Board/lib.test.ts +106 -0
  90. package/src/components/Board/lib.ts +34 -3
  91. package/src/components/Board/selectors.ts +17 -5
  92. package/src/components/Button/Button.module.scss +1 -1
  93. package/src/components/Modal/Modal.module.scss +0 -4
  94. package/src/components/Results/Header.tsx +30 -5
  95. package/src/components/Results/Result.tsx +45 -55
  96. package/src/components/Results/Results.module.scss +0 -126
  97. package/src/components/Results/Results.module.scss.d.ts +0 -10
  98. package/src/components/Results/Results.tsx +25 -5
  99. package/src/components/Solver/Solver.module.scss +4 -4
  100. package/src/components/Solver/Solver.tsx +5 -3
  101. package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.module.scss +5 -1
  102. package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.module.scss.d.ts +1 -0
  103. package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +5 -2
  104. package/src/components/Table/Cell.tsx +42 -0
  105. package/src/components/Table/Header.tsx +11 -0
  106. package/src/components/{Results → Table}/HeaderButton.tsx +22 -14
  107. package/src/components/Table/Row.tsx +59 -0
  108. package/src/components/{ResultsInput/ResultsInput.tsx → Table/Search.tsx} +9 -11
  109. package/src/components/Table/Table.module.scss +147 -0
  110. package/src/components/Table/Table.module.scss.d.ts +19 -0
  111. package/src/components/Table/index.ts +5 -0
  112. package/src/components/Tile/Tile.module.scss +2 -1
  113. package/src/hooks/useColumns.ts +7 -5
  114. package/src/hooks/useIsCompactLayout.ts +14 -0
  115. package/src/i18n/languages/english.json +6 -1
  116. package/src/i18n/languages/french.json +6 -1
  117. package/src/i18n/languages/german.json +6 -1
  118. package/src/i18n/languages/persian.json +6 -1
  119. package/src/i18n/languages/polish.json +6 -1
  120. package/src/i18n/languages/romanian.json +6 -1
  121. package/src/i18n/languages/spanish.json +6 -1
  122. package/src/i18n/languages/turkish.json +6 -1
  123. package/src/icons/QuestionSquare.svg +5 -0
  124. package/src/lib/createCoordinatesComparator.ts +23 -0
  125. package/src/lib/createKeyComparator.ts +1 -4
  126. package/src/lib/createSortComparator.ts +22 -0
  127. package/src/lib/getCoordinates.test.ts +21 -0
  128. package/src/lib/getCoordinates.ts +16 -0
  129. package/src/lib/getNextSort.ts +12 -0
  130. package/src/modals/RemainingTilesModal/RemainingTilesModal.tsx +3 -1
  131. package/src/modals/RemainingTilesModal/components/Character/Character.tsx +8 -9
  132. package/src/modals/ResultsModal/ResultsModal.tsx +14 -10
  133. package/src/modals/WordsModal/WordsModal.module.scss +16 -27
  134. package/src/modals/WordsModal/WordsModal.module.scss.d.ts +3 -6
  135. package/src/modals/WordsModal/WordsModal.tsx +56 -42
  136. package/src/modals/WordsModal/components/WordsTable/WordRow.tsx +92 -0
  137. package/src/modals/WordsModal/components/WordsTable/WordsTable.module.scss +69 -0
  138. package/src/modals/WordsModal/components/WordsTable/WordsTable.module.scss.d.ts +16 -0
  139. package/src/modals/WordsModal/components/WordsTable/WordsTable.tsx +137 -0
  140. package/src/modals/WordsModal/components/WordsTable/index.ts +1 -0
  141. package/src/modals/WordsModal/components/index.ts +1 -0
  142. package/src/pages/api/verify.ts +7 -6
  143. package/src/pages/index.tsx +28 -3
  144. package/src/parameters/index.ts +2 -0
  145. package/src/sdk/verify.ts +3 -2
  146. package/src/solver-worker/client.test.ts +10 -3
  147. package/src/solver-worker/index.worker.ts +7 -7
  148. package/src/solver-worker/messages.ts +3 -3
  149. package/src/state/hoveredWord/index.ts +4 -0
  150. package/src/state/hoveredWord/initialState.ts +5 -0
  151. package/src/state/hoveredWord/selectors.ts +5 -0
  152. package/src/state/hoveredWord/slice.ts +18 -0
  153. package/src/state/hoveredWord/types.ts +5 -0
  154. package/src/state/index.ts +1 -0
  155. package/src/state/localStorage.ts +13 -2
  156. package/src/state/results/lib.ts +9 -26
  157. package/src/state/results/selectors.ts +9 -1
  158. package/src/state/results/slice.ts +4 -16
  159. package/src/state/sagas.ts +26 -1
  160. package/src/state/selectors.ts +18 -1
  161. package/src/state/store.ts +2 -0
  162. package/src/state/types.ts +2 -0
  163. package/src/state/verify/initialState.ts +7 -0
  164. package/src/state/verify/lib.test.ts +55 -0
  165. package/src/state/verify/lib.ts +49 -0
  166. package/src/state/verify/selectors.ts +37 -0
  167. package/src/state/verify/slice.ts +13 -2
  168. package/src/state/verify/types.ts +6 -2
  169. package/src/styles/_tokens.scss +2 -0
  170. package/src/styles/mixins.scss +5 -0
  171. package/src/styles/variables.module.scss +1 -0
  172. package/src/styles/variables.module.scss.d.ts +1 -0
  173. package/src/styles/variables.scss +1 -1
  174. package/src/types/index.ts +24 -11
  175. package/tsconfig.tsbuildinfo +1 -1
  176. package/.next/server/chunks/316.js +0 -1
  177. package/.next/server/chunks/916.js +0 -1
  178. package/.next/static/chunks/106.e414e88694add27f.js +0 -1
  179. package/.next/static/chunks/127.125d896a19061d71.js +0 -1
  180. package/.next/static/chunks/18.8b91e137d239e15c.js +0 -1
  181. package/.next/static/chunks/583.7a46807be14c377e.js +0 -1
  182. package/.next/static/chunks/711.ba7b8f900dfd40d0.js +0 -1
  183. package/.next/static/chunks/912.ff8037ba9d4db5c8.js +0 -1
  184. package/.next/static/chunks/pages/_app-2e607dcd4135f340.js +0 -1
  185. package/.next/static/chunks/pages/index-e0087247c995328d.js +0 -1
  186. package/.next/static/chunks/webpack-cfb34d175e081981.js +0 -1
  187. package/.next/static/css/b74cd7de82dabcdd.css +0 -1
  188. package/.next/static/css/c403ce739a9c0d83.css +0 -1
  189. package/.next/static/css/fbfdce70731d0d2b.css +0 -1
  190. package/src/components/Results/Cell.tsx +0 -32
  191. package/src/components/ResultsInput/ResultsInput.module.scss +0 -12
  192. package/src/components/ResultsInput/ResultsInput.module.scss.d.ts +0 -7
  193. package/src/components/ResultsInput/index.ts +0 -1
  194. /package/.next/static/{5KOWzYqfY1Z2rjrzptr8D → nvGZh1gPuX98L07YmxlYD}/_ssgManifest.js +0 -0
@@ -0,0 +1,49 @@
1
+ import { type BoardWord, type ShowCoordinates } from '@scrabble-solver/types';
2
+
3
+ import { createCoordinatesComparator } from '@/lib/createCoordinatesComparator';
4
+ import { createKeyComparator } from '@/lib/createKeyComparator';
5
+ import { createRegExp } from '@/lib/createRegExp';
6
+ import { createSortComparator } from '@/lib/createSortComparator';
7
+ import { getCoordinates } from '@/lib/getCoordinates';
8
+ import { numberComparator } from '@/lib/numberComparator';
9
+ import { type ComparatorFactory, type GroupedWords, type Sort, type VerifiedWord, WordColumnId } from '@/types';
10
+
11
+ export const getWordCoordinates = (word: BoardWord, showCoordinates: ShowCoordinates): string => {
12
+ return getCoordinates({ isHorizontal: word.direction === 'horizontal', x: word.x, y: word.y }, showCoordinates);
13
+ };
14
+
15
+ export const groupWords = (words: VerifiedWord[], query: string): GroupedWords => {
16
+ const regExp = createRegExp(query);
17
+
18
+ return words.reduce<GroupedWords>(
19
+ (groupedWords, word) => {
20
+ if (word.word.match(regExp)) {
21
+ groupedWords.matching.push(word);
22
+ } else {
23
+ groupedWords.other.push(word);
24
+ }
25
+
26
+ return groupedWords;
27
+ },
28
+ { matching: [], other: [] },
29
+ );
30
+ };
31
+
32
+ const comparators: Record<WordColumnId, ComparatorFactory<VerifiedWord>> = {
33
+ [WordColumnId.Coordinates]: (locale: string, showCoordinates: ShowCoordinates) => {
34
+ return createCoordinatesComparator({ getItemCoordinates: getWordCoordinates, locale, showCoordinates });
35
+ },
36
+ [WordColumnId.Validity]: () => (a, b) => {
37
+ return numberComparator(Number(a.isValid), Number(b.isValid));
38
+ },
39
+ [WordColumnId.Word]: (locale: string) => createKeyComparator('word', locale),
40
+ };
41
+
42
+ export const sortWords = (
43
+ words: VerifiedWord[],
44
+ sort: Sort<WordColumnId>,
45
+ locale: string,
46
+ showCoordinates: ShowCoordinates,
47
+ ): VerifiedWord[] => {
48
+ return [...words].sort(createSortComparator({ comparators, locale, showCoordinates, sort }));
49
+ };
@@ -1,9 +1,46 @@
1
1
  import { createSelector } from '@reduxjs/toolkit';
2
2
 
3
+ import { createRegExp } from '@/lib/createRegExp';
4
+
5
+ import { selectLocale, selectShowCoordinates } from '../settings';
3
6
  import type { RootState } from '../types';
4
7
 
8
+ import { getWordCoordinates, groupWords, sortWords } from './lib';
9
+
10
+ const selectWordIndex = (_: unknown, index: number): number => index;
11
+
5
12
  export const selectVerify = (state: RootState) => state.verify;
6
13
 
14
+ export const selectLastVerifiedBoard = createSelector([selectVerify], (verify) => verify.lastSolvedParameters.board);
15
+
7
16
  export const selectInvalidWords = createSelector([selectVerify], (verify) => verify.invalidWords);
8
17
 
9
18
  export const selectValidWords = createSelector([selectVerify], (verify) => verify.validWords);
19
+
20
+ export const selectWordsQuery = createSelector([selectVerify], (verify) => verify.query);
21
+
22
+ export const selectWordsSort = createSelector([selectVerify], (verify) => verify.sort);
23
+
24
+ export const selectCreatedWords = createSelector([selectInvalidWords, selectValidWords], (invalidWords, validWords) => {
25
+ return [...invalidWords, ...validWords];
26
+ });
27
+
28
+ const selectSortedWords = createSelector(
29
+ [selectCreatedWords, selectWordsSort, selectLocale, selectShowCoordinates],
30
+ sortWords,
31
+ );
32
+
33
+ export const selectProcessedWords = createSelector([selectSortedWords, selectWordsQuery], (words, query) => {
34
+ const { matching, other } = groupWords(words, query);
35
+ return [...matching, ...other];
36
+ });
37
+
38
+ export const selectIsWordMatching = createSelector(
39
+ [selectProcessedWords, selectWordsQuery, selectWordIndex],
40
+ (words, query, index) => createRegExp(query).test(words[index].word),
41
+ );
42
+
43
+ export const selectWordCoordinates = createSelector(
44
+ [selectProcessedWords, selectShowCoordinates, selectWordIndex],
45
+ (words, showCoordinates, index) => getWordCoordinates(words[index], showCoordinates),
46
+ );
@@ -1,12 +1,15 @@
1
1
  import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
2
2
  import { type Board } from '@scrabble-solver/types';
3
3
 
4
+ import { getNextSort } from '@/lib/getNextSort';
5
+ import { type VerifiedWord, type WordColumnId } from '@/types';
6
+
4
7
  import { verifyInitialState } from './initialState';
5
8
 
6
9
  interface VerifyParameters {
7
10
  board: Board;
8
- invalidWords: string[];
9
- validWords: string[];
11
+ invalidWords: VerifiedWord[];
12
+ validWords: VerifiedWord[];
10
13
  }
11
14
 
12
15
  export const verifySlice = createSlice({
@@ -17,10 +20,18 @@ export const verifySlice = createSlice({
17
20
  return { ...state, isLoading: true };
18
21
  },
19
22
 
23
+ changeQuery: (state, action: PayloadAction<string>) => {
24
+ return { ...state, query: action.payload };
25
+ },
26
+
20
27
  submitFailure: (state) => {
21
28
  return { ...state, isLoading: false };
22
29
  },
23
30
 
31
+ sort: (state, action: PayloadAction<WordColumnId>) => {
32
+ return { ...state, sort: getNextSort(state.sort, action.payload) };
33
+ },
34
+
24
35
  submitSuccess: (state, action: PayloadAction<VerifyParameters>) => {
25
36
  const { board, invalidWords, validWords } = action.payload;
26
37
  return { ...state, isLoading: false, lastSolvedParameters: { board }, invalidWords, validWords };
@@ -1,3 +1,5 @@
1
+ import type { Sort, VerifiedWord, WordColumnId } from '@/types';
2
+
1
3
  import type { BoardState } from '../board';
2
4
 
3
5
  export interface VerifyState {
@@ -5,6 +7,8 @@ export interface VerifyState {
5
7
  lastSolvedParameters: {
6
8
  board: BoardState;
7
9
  };
8
- invalidWords: string[];
9
- validWords: string[];
10
+ invalidWords: VerifiedWord[];
11
+ query: string;
12
+ sort: Sort<WordColumnId>;
13
+ validWords: VerifiedWord[];
10
14
  }
@@ -10,6 +10,8 @@ $breakpoint-m: 992px;
10
10
  $breakpoint-l: 1200px;
11
11
  $breakpoint-xl: 1400px;
12
12
 
13
+ $breakpoint-height-l: 860px;
14
+
13
15
  $border-color: #cdcdcd;
14
16
  $border-color-light: #d9d9d9;
15
17
  $border-radius: 5px;
@@ -10,6 +10,11 @@
10
10
  ),
11
11
  $media-expressions: (
12
12
  touch: '(hover: none)',
13
+ /**
14
+ * Keep in sync with useIsCompactLayout
15
+ */
16
+ compact: '(max-width: #{$breakpoint-l - 1px}), (max-height: #{$breakpoint-height-l - 1px})',
17
+ desktop: '(min-width: #{$breakpoint-l}) and (min-height: #{$breakpoint-height-l})',
13
18
  )
14
19
  );
15
20
 
@@ -6,6 +6,7 @@
6
6
  breakpointM: strip-unit($breakpoint-m);
7
7
  breakpointL: strip-unit($breakpoint-l);
8
8
  breakpointXl: strip-unit($breakpoint-xl);
9
+ breakpointHeightL: strip-unit($breakpoint-height-l);
9
10
 
10
11
  borderColorLight: $border-color-light;
11
12
  borderWidth: strip-unit($border-width);
@@ -2,6 +2,7 @@
2
2
  declare const styles: {
3
3
  readonly borderColorLight: string;
4
4
  readonly borderWidth: string;
5
+ readonly breakpointHeightL: string;
5
6
  readonly breakpointL: string;
6
7
  readonly breakpointM: string;
7
8
  readonly breakpointS: string;
@@ -153,7 +153,7 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
153
153
  --components-spacing: var(--spacing--l);
154
154
  }
155
155
 
156
- @include media('<l') {
156
+ @include media('compact') {
157
157
  --dictionary--height: var(--dictionary--height--mobile);
158
158
  --logo--height: #{$logo-height-small};
159
159
  --solver-column-total: 0px;
@@ -1,8 +1,9 @@
1
- import { type Result } from '@scrabble-solver/types';
2
- import { type FunctionComponent, type SVGAttributes } from 'react';
1
+ import { type BoardWord, type Result, type ShowCoordinates } from '@scrabble-solver/types';
3
2
 
4
3
  export type Comparator<T> = (a: T, B: T) => number;
5
4
 
5
+ export type ComparatorFactory<T> = (locale: string, showCoordinates: ShowCoordinates) => Comparator<T>;
6
+
6
7
  export type AutoGroupTiles = 'left' | 'right' | null;
7
8
 
8
9
  export type CellFilterType = 'include' | 'exclude';
@@ -26,8 +27,8 @@ export interface Point {
26
27
 
27
28
  export type Rack = (string | null)[];
28
29
 
29
- export interface Sort {
30
- column: ResultColumnId;
30
+ export interface Sort<Id extends string = ResultColumnId> {
31
+ column: Id;
31
32
  direction: SortDirection;
32
33
  }
33
34
 
@@ -61,12 +62,10 @@ export enum ResultColumnId {
61
62
  WordsCount = 'words-count',
62
63
  }
63
64
 
64
- export interface ResultColumn {
65
- className: string;
66
- Icon?: FunctionComponent<SVGAttributes<SVGElement>>;
67
- id: ResultColumnId;
68
- translationKey: TranslationKey;
69
- width?: number;
65
+ export enum WordColumnId {
66
+ Coordinates = 'coordinates',
67
+ Validity = 'validity',
68
+ Word = 'word',
70
69
  }
71
70
 
72
71
  export interface GroupedResults {
@@ -74,6 +73,15 @@ export interface GroupedResults {
74
73
  other: Result[];
75
74
  }
76
75
 
76
+ export interface GroupedWords {
77
+ matching: VerifiedWord[];
78
+ other: VerifiedWord[];
79
+ }
80
+
81
+ export interface VerifiedWord extends BoardWord {
82
+ isValid: boolean;
83
+ }
84
+
77
85
  export type TranslationKey =
78
86
  | 'cell.enter-word'
79
87
  | 'cell.filter-cell.exclude'
@@ -135,6 +143,7 @@ export type TranslationKey =
135
143
  | 'results.input.placeholder'
136
144
  | 'results.insert'
137
145
  | 'results.preview'
146
+ | 'results.select'
138
147
  | 'results.solve'
139
148
  | 'settings'
140
149
  | 'settings.autoGroupTiles'
@@ -154,8 +163,12 @@ export type TranslationKey =
154
163
  | 'settings.showCoordinates.alternative'
155
164
  | 'settings.showCoordinates.original'
156
165
  | 'words'
166
+ | 'words.empty-state.no-words'
167
+ | 'words.input.placeholder'
157
168
  | 'words.invalid'
158
- | 'words.valid';
169
+ | 'words.preview'
170
+ | 'words.valid'
171
+ | 'words.validity';
159
172
 
160
173
  export type Translate = (key: TranslationKey, replacements?: Record<string, string>) => string;
161
174