scrabble-solver 2.13.6 → 2.13.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 (131) hide show
  1. package/.nx/cache/d/server-process.json +1 -0
  2. package/.nx/cache/file-map.json +1293 -1298
  3. package/.nx/cache/lockfile.hash +1 -1
  4. package/.nx/cache/nx_files.nxt +0 -0
  5. package/.nx/cache/parsed-lock-file.json +306 -361
  6. package/.nx/cache/project-graph.json +316 -382
  7. package/.nx/workspace-data/file-map.json +2594 -0
  8. package/.nx/workspace-data/lockfile.hash +1 -0
  9. package/.nx/workspace-data/parsed-lock-file.json +31666 -0
  10. package/.nx/workspace-data/project-graph.json +31937 -0
  11. package/README.md +10 -19
  12. package/bump-version.js +15 -9
  13. package/lerna.json +1 -1
  14. package/package.json +9 -9
  15. package/packages/configs/package.json +3 -3
  16. package/packages/constants/package.json +1 -1
  17. package/packages/dictionaries/package-lock.json +2 -2
  18. package/packages/dictionaries/package.json +4 -4
  19. package/packages/logger/package-lock.json +2 -2
  20. package/packages/logger/package.json +1 -1
  21. package/packages/scrabble-solver/.next/BUILD_ID +1 -1
  22. package/packages/scrabble-solver/.next/build-manifest.json +11 -11
  23. package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
  24. package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
  25. package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
  26. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
  27. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/0.pack +0 -0
  28. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
  29. package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
  30. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
  31. package/packages/scrabble-solver/.next/prerender-manifest.js +1 -1
  32. package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
  33. package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
  34. package/packages/scrabble-solver/.next/server/chunks/577.js +1 -1
  35. package/packages/scrabble-solver/.next/server/chunks/807.js +1 -1
  36. package/packages/scrabble-solver/.next/server/chunks/977.js +1 -1
  37. package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
  38. package/packages/scrabble-solver/.next/server/pages/404.html +1 -1
  39. package/packages/scrabble-solver/.next/server/pages/500.html +1 -1
  40. package/packages/scrabble-solver/.next/server/pages/_app.js +1 -1
  41. package/packages/scrabble-solver/.next/server/pages/_error.js +1 -1
  42. package/packages/scrabble-solver/.next/server/pages/api/solve.js +1 -1
  43. package/packages/scrabble-solver/.next/server/pages/index.html +1 -1
  44. package/packages/scrabble-solver/.next/server/pages/index.js +1 -1
  45. package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
  46. package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -1
  47. package/packages/scrabble-solver/.next/static/7zESQYo9UAqNh9LV0b7Sd/_buildManifest.js +1 -0
  48. package/packages/scrabble-solver/.next/static/chunks/{main-6e708370ad13b1f9.js → main-b5b360c6afb66b05.js} +1 -1
  49. package/packages/scrabble-solver/.next/static/chunks/pages/{404-129e0943628b6fab.js → 404-63b972b24be99c62.js} +1 -1
  50. package/packages/scrabble-solver/.next/static/chunks/pages/_app-a2848b7efa6bb6b0.js +17 -0
  51. package/packages/scrabble-solver/.next/static/chunks/pages/index-7b73be2915cc7099.js +1 -0
  52. package/packages/scrabble-solver/.next/static/css/6682db14f926d4c7.css +1 -0
  53. package/packages/scrabble-solver/.next/static/css/b37850c8d5270d91.css +2 -0
  54. package/packages/scrabble-solver/.next/trace +44 -44
  55. package/packages/scrabble-solver/package-lock.json +5 -6
  56. package/packages/scrabble-solver/package.json +11 -12
  57. package/packages/scrabble-solver/public/service-worker.js +1 -1
  58. package/packages/scrabble-solver/src/components/Alert/Alert.module.scss +3 -12
  59. package/packages/scrabble-solver/src/components/Board/Board.module.scss +1 -4
  60. package/packages/scrabble-solver/src/components/Board/BoardPure.tsx +1 -1
  61. package/packages/scrabble-solver/src/components/Board/components/Actions/Actions.module.scss +7 -27
  62. package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.module.scss +5 -32
  63. package/packages/scrabble-solver/src/components/Board/components/InputPrompt/InputPrompt.module.scss +4 -18
  64. package/packages/scrabble-solver/src/components/Board/hooks/useBackgroundImage.tsx +15 -4
  65. package/packages/scrabble-solver/src/components/Board/hooks/useGrid.ts +13 -5
  66. package/packages/scrabble-solver/src/components/Board/lib/index.ts +0 -1
  67. package/packages/scrabble-solver/src/components/Button/Button.module.scss +1 -8
  68. package/packages/scrabble-solver/src/components/Button/Button.tsx +16 -17
  69. package/packages/scrabble-solver/src/components/Button/Link.tsx +15 -16
  70. package/packages/scrabble-solver/src/components/Dictionary/Dictionary.module.scss +1 -8
  71. package/packages/scrabble-solver/src/components/IconButton/IconButton.tsx +8 -8
  72. package/packages/scrabble-solver/src/components/IconButton/Link.tsx +8 -8
  73. package/packages/scrabble-solver/src/components/Loading/Loading.module.scss +1 -4
  74. package/packages/scrabble-solver/src/components/Modal/Modal.module.scss +2 -16
  75. package/packages/scrabble-solver/src/components/Rack/Rack.module.scss +4 -18
  76. package/packages/scrabble-solver/src/components/Rack/components/InputPrompt/InputPrompt.module.scss +1 -4
  77. package/packages/scrabble-solver/src/components/Results/Cell.tsx +4 -5
  78. package/packages/scrabble-solver/src/components/Results/HeaderButton.tsx +25 -22
  79. package/packages/scrabble-solver/src/components/Results/Result.tsx +15 -3
  80. package/packages/scrabble-solver/src/components/Results/Results.module.scss +31 -48
  81. package/packages/scrabble-solver/src/components/Results/Results.tsx +1 -1
  82. package/packages/scrabble-solver/src/components/Results/getCoordinatesColumn.ts +15 -0
  83. package/packages/scrabble-solver/src/components/Results/getLocaleColumns.ts +7 -0
  84. package/packages/scrabble-solver/src/components/Results/types.ts +1 -0
  85. package/packages/scrabble-solver/src/components/Results/useColumns.ts +10 -7
  86. package/packages/scrabble-solver/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.module.scss +9 -40
  87. package/packages/scrabble-solver/src/components/Tile/Tile.module.scss +6 -26
  88. package/packages/scrabble-solver/src/components/Tooltip/Tooltip.tsx +28 -0
  89. package/packages/scrabble-solver/src/components/Tooltip/TooltipContent.tsx +53 -0
  90. package/packages/scrabble-solver/src/components/Tooltip/TooltipTrigger.tsx +26 -0
  91. package/packages/scrabble-solver/src/components/Tooltip/context.ts +17 -0
  92. package/packages/scrabble-solver/src/components/Tooltip/index.ts +1 -1
  93. package/packages/scrabble-solver/src/components/Tooltip/useTooltip.ts +54 -0
  94. package/packages/scrabble-solver/src/components/index.ts +1 -2
  95. package/packages/scrabble-solver/src/hooks/index.ts +0 -1
  96. package/packages/scrabble-solver/src/i18n/languages/german.json +1 -1
  97. package/packages/scrabble-solver/src/icons/index.ts +0 -2
  98. package/packages/scrabble-solver/src/lib/getCoordinates.ts +18 -0
  99. package/packages/scrabble-solver/src/lib/groupResults.ts +16 -11
  100. package/packages/scrabble-solver/src/lib/index.ts +2 -1
  101. package/packages/scrabble-solver/src/lib/sortResults.ts +1 -0
  102. package/packages/scrabble-solver/src/modals/KeyMapModal/components/Mapping/Mapping.module.scss +2 -2
  103. package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.module.scss +2 -15
  104. package/packages/scrabble-solver/src/modals/RemainingTilesModal/RemainingTilesModal.module.scss +1 -7
  105. package/packages/scrabble-solver/src/modals/WordsModal/WordsModal.module.scss +2 -15
  106. package/packages/scrabble-solver/src/pages/_app.tsx +5 -1
  107. package/packages/scrabble-solver/src/parameters/index.ts +1 -0
  108. package/packages/scrabble-solver/src/styles/mixins.scss +2 -5
  109. package/packages/scrabble-solver/src/types/index.ts +1 -0
  110. package/packages/solver/package-lock.json +2 -2
  111. package/packages/solver/package.json +5 -5
  112. package/packages/types/package.json +2 -2
  113. package/packages/word-definitions/package-lock.json +2 -2
  114. package/packages/word-definitions/package.json +2 -2
  115. package/packages/word-lists/package-lock.json +3 -3
  116. package/packages/word-lists/package.json +3 -3
  117. package/packages/scrabble-solver/.next/static/4GWIKe7khKxREyq3ZamDK/_buildManifest.js +0 -1
  118. package/packages/scrabble-solver/.next/static/chunks/pages/_app-cccda36d00fa2328.js +0 -17
  119. package/packages/scrabble-solver/.next/static/chunks/pages/index-caaf20b2488cb10e.js +0 -1
  120. package/packages/scrabble-solver/.next/static/css/11366b7489cf90ac.css +0 -1
  121. package/packages/scrabble-solver/.next/static/css/f549d7823f599b8d.css +0 -2
  122. package/packages/scrabble-solver/src/components/Checkbox/Checkbox.module.scss +0 -45
  123. package/packages/scrabble-solver/src/components/Checkbox/Checkbox.tsx +0 -38
  124. package/packages/scrabble-solver/src/components/Checkbox/index.ts +0 -1
  125. package/packages/scrabble-solver/src/components/Tooltip/useTooltip.tsx +0 -134
  126. package/packages/scrabble-solver/src/hooks/usePortal.tsx +0 -47
  127. package/packages/scrabble-solver/src/icons/CheckboxChecked.svg +0 -4
  128. package/packages/scrabble-solver/src/icons/CheckboxEmpty.svg +0 -4
  129. package/packages/scrabble-solver/src/lib/canUseDom.ts +0 -3
  130. /package/packages/scrabble-solver/.next/static/{4GWIKe7khKxREyq3ZamDK → 7zESQYo9UAqNh9LV0b7Sd}/_ssgManifest.js +0 -0
  131. /package/packages/scrabble-solver/src/{components/Board/lib → lib}/getCoordinate.ts +0 -0
@@ -1,12 +1,13 @@
1
1
  import { useMediaQueries } from 'hooks';
2
2
  import { LOCALE_FEATURES } from 'i18n';
3
- import { selectLocale, useTypedSelector } from 'state';
3
+ import { selectLocale, selectShowCoordinates, useTypedSelector } from 'state';
4
4
  import { ResultColumn } from 'types';
5
5
 
6
+ import getCoordinatesColumn from './getCoordinatesColumn';
6
7
  import getLocaleColumns from './getLocaleColumns';
7
8
  import { Column } from './types';
8
9
 
9
- const COLUMNS_XS = [ResultColumn.Word, ResultColumn.Points];
10
+ const COLUMNS_XS = [ResultColumn.Coordinates, ResultColumn.Word, ResultColumn.Points];
10
11
 
11
12
  const COLUMNS_S = [...COLUMNS_XS, ResultColumn.BlanksCount, ResultColumn.WordsCount];
12
13
 
@@ -17,25 +18,27 @@ const COLUMNS_L = [...COLUMNS_XS];
17
18
  const useColumns = (): Column[] => {
18
19
  const locale = useTypedSelector(selectLocale);
19
20
  const localeColumns = getLocaleColumns(LOCALE_FEATURES[locale]);
21
+ const showCoordinates = useTypedSelector(selectShowCoordinates);
22
+ const columns = showCoordinates === 'hidden' ? localeColumns : [getCoordinatesColumn(), ...localeColumns];
20
23
  const { isLessThanXs, isLessThanS, isLessThanM, isLessThanL } = useMediaQueries();
21
24
 
22
25
  if (isLessThanXs) {
23
- return localeColumns.filter((column) => COLUMNS_XS.includes(column.id));
26
+ return columns.filter((column) => COLUMNS_XS.includes(column.id));
24
27
  }
25
28
 
26
29
  if (isLessThanS) {
27
- return localeColumns.filter((column) => COLUMNS_S.includes(column.id));
30
+ return columns.filter((column) => COLUMNS_S.includes(column.id));
28
31
  }
29
32
 
30
33
  if (isLessThanM) {
31
- return localeColumns.filter((column) => COLUMNS_M.includes(column.id));
34
+ return columns.filter((column) => COLUMNS_M.includes(column.id));
32
35
  }
33
36
 
34
37
  if (isLessThanL) {
35
- return localeColumns.filter((column) => COLUMNS_L.includes(column.id));
38
+ return columns.filter((column) => COLUMNS_L.includes(column.id));
36
39
  }
37
40
 
38
- return localeColumns;
41
+ return columns;
39
42
  };
40
43
 
41
44
  export default useColumns;
@@ -82,23 +82,11 @@
82
82
  .points {
83
83
  flex: 0 0 auto;
84
84
  font-weight: bold;
85
+ border-inline-end: var(--border);
85
86
 
86
- [dir='ltr'] & {
87
- border-right: var(--border);
88
-
89
- @include media('<xs') {
90
- border-right: none;
91
- padding-right: var(--spacing--xs);
92
- }
93
- }
94
-
95
- [dir='rtl'] & {
96
- border-left: var(--border);
97
-
98
- @include media('<xs') {
99
- border-left: none;
100
- padding-left: var(--spacing--xs);
101
- }
87
+ @include media('<xs') {
88
+ border-inline-end: none;
89
+ padding-inline-end: var(--spacing--xs);
102
90
  }
103
91
  }
104
92
 
@@ -110,40 +98,21 @@
110
98
  text-align: center;
111
99
  white-space: pre-wrap;
112
100
 
113
- [dir='ltr'] & {
114
- @include media('<xs') {
115
- padding: var(--spacing--m);
116
- text-align: left;
117
- }
118
- }
119
-
120
- [dir='rtl'] & {
121
- @include media('<xs') {
122
- padding: var(--spacing--m);
123
- text-align: right;
124
- }
101
+ @include media('<xs') {
102
+ padding: var(--spacing--m);
103
+ text-align: start;
125
104
  }
126
105
  }
127
106
 
128
107
  .iconContainer {
129
108
  flex: 0 0 auto;
130
109
  display: flex;
131
-
132
- [dir='ltr'] & {
133
- padding-right: var(--spacing--l);
134
- }
135
-
136
- [dir='rtl'] & {
137
- padding-left: var(--spacing--l);
138
- }
110
+ padding-inline-end: var(--spacing--l);
139
111
  }
140
112
 
141
113
  .spinnerContainer {
142
114
  position: absolute;
143
- top: 0;
144
- right: 0;
145
- bottom: 0;
146
- left: 0;
115
+ inset: 0;
147
116
  display: flex;
148
117
  align-items: center;
149
118
  justify-content: center;
@@ -76,10 +76,7 @@
76
76
 
77
77
  .input {
78
78
  position: absolute;
79
- top: 0;
80
- right: 0;
81
- bottom: 0;
82
- left: 0;
79
+ inset: 0;
83
80
  width: 100%;
84
81
  height: 100%;
85
82
  border: none;
@@ -98,6 +95,8 @@
98
95
  @include text-stroke(var(--background-color), 1px);
99
96
 
100
97
  position: absolute;
98
+ inset-block-end: 1%;
99
+ inset-inline-end: 9%;
101
100
  font-weight: bold;
102
101
  user-select: none;
103
102
  pointer-events: none;
@@ -106,16 +105,6 @@
106
105
  @include media('<xs') {
107
106
  display: none;
108
107
  }
109
-
110
- [dir='ltr'] & {
111
- bottom: 1%;
112
- right: 9%;
113
- }
114
-
115
- [dir='rtl'] & {
116
- top: 1%;
117
- left: 9%;
118
- }
119
108
  }
120
109
 
121
110
  .alert {
@@ -124,6 +113,9 @@
124
113
  position: absolute;
125
114
  width: var(--size);
126
115
  height: var(--size);
116
+ inset-block-start: 0;
117
+ inset-inline-end: 0;
118
+ border-start-end-radius: inherit;
127
119
  background: radial-gradient(
128
120
  var(--color--error--opposite),
129
121
  var(--color--error--opposite) 85%,
@@ -132,16 +124,4 @@
132
124
  );
133
125
  color: var(--color--error);
134
126
  pointer-events: none;
135
-
136
- [dir='ltr'] & {
137
- top: 0;
138
- right: 0;
139
- border-top-right-radius: inherit;
140
- }
141
-
142
- [dir='rtl'] & {
143
- top: 0;
144
- left: 0;
145
- border-top-left-radius: inherit;
146
- }
147
127
  }
@@ -0,0 +1,28 @@
1
+ import type { Placement } from '@floating-ui/react';
2
+ import { FunctionComponent, ReactNode } from 'react';
3
+
4
+ import { TooltipContext } from './context';
5
+ import { TooltipContent } from './TooltipContent';
6
+ import { TooltipTrigger } from './TooltipTrigger';
7
+ import { useTooltip } from './useTooltip';
8
+
9
+ interface Props {
10
+ children: ReactNode;
11
+ placement?: Placement;
12
+ tooltip?: ReactNode;
13
+ }
14
+
15
+ export const Tooltip: FunctionComponent<Props> = ({ children, placement, tooltip }) => {
16
+ const state = useTooltip({ placement });
17
+
18
+ if (!tooltip) {
19
+ return children;
20
+ }
21
+
22
+ return (
23
+ <TooltipContext.Provider value={state}>
24
+ <TooltipTrigger>{children}</TooltipTrigger>
25
+ <TooltipContent>{tooltip}</TooltipContent>
26
+ </TooltipContext.Provider>
27
+ );
28
+ };
@@ -0,0 +1,53 @@
1
+ import { FloatingArrow, FloatingPortal, useDelayGroup, useMergeRefs, useTransitionStyles } from '@floating-ui/react';
2
+ import { forwardRef, HTMLProps } from 'react';
3
+
4
+ import { TOOLTIP_DURATION } from 'parameters';
5
+
6
+ import { useTooltipContext } from './context';
7
+ import styles from './Tooltip.module.scss';
8
+
9
+ type Props = HTMLProps<HTMLDivElement>;
10
+
11
+ const INSTANT_DURATION = 0;
12
+
13
+ export const TooltipContent = forwardRef<HTMLDivElement, Props>((props, ref) => {
14
+ const state = useTooltipContext();
15
+ const { context } = state;
16
+ const { isInstantPhase, currentId } = useDelayGroup(context, { id: context.floatingId });
17
+ const finalRef = useMergeRefs([state.refs.setFloating, ref]);
18
+
19
+ const instantPhaseDuration = {
20
+ open: INSTANT_DURATION,
21
+ close: currentId === context.floatingId ? TOOLTIP_DURATION : INSTANT_DURATION,
22
+ };
23
+
24
+ const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {
25
+ duration: isInstantPhase ? instantPhaseDuration : TOOLTIP_DURATION,
26
+ initial: {
27
+ opacity: 0,
28
+ },
29
+ });
30
+
31
+ if (!isMounted) {
32
+ return null;
33
+ }
34
+
35
+ return (
36
+ <FloatingPortal>
37
+ <div
38
+ className={styles.tooltip}
39
+ ref={finalRef}
40
+ style={{
41
+ ...state.floatingStyles,
42
+ ...props.style,
43
+ ...transitionStyles,
44
+ }}
45
+ {...state.getFloatingProps(props)}
46
+ >
47
+ <div>{props.children}</div>
48
+
49
+ <FloatingArrow className={styles.arrow} context={context} ref={state.arrowRef} />
50
+ </div>
51
+ </FloatingPortal>
52
+ );
53
+ });
@@ -0,0 +1,26 @@
1
+ import { useMergeRefs } from '@floating-ui/react';
2
+ import { HTMLProps, cloneElement, forwardRef, isValidElement } from 'react';
3
+
4
+ import { useTooltipContext } from './context';
5
+
6
+ type Props = HTMLProps<HTMLElement>;
7
+
8
+ export const TooltipTrigger = forwardRef<HTMLElement, Props>(({ children, ...props }, ref) => {
9
+ const state = useTooltipContext();
10
+ const childrenElement = children as any; // eslint-disable-line @typescript-eslint/no-explicit-any
11
+ const finalRef = useMergeRefs([state.refs.setReference, ref, childrenElement.ref]);
12
+
13
+ if (!isValidElement(children)) {
14
+ throw new Error("TooltipTrigger's children are not a valid element");
15
+ }
16
+
17
+ return cloneElement(
18
+ children,
19
+ state.getReferenceProps({
20
+ ref: finalRef,
21
+ ...props,
22
+ ...children.props,
23
+ 'data-state': state.open ? 'open' : 'closed',
24
+ }),
25
+ );
26
+ });
@@ -0,0 +1,17 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ import { useTooltip } from './useTooltip';
4
+
5
+ type TooltipContextType = ReturnType<typeof useTooltip> | null;
6
+
7
+ export const TooltipContext = createContext<TooltipContextType>(null);
8
+
9
+ export const useTooltipContext = () => {
10
+ const context = useContext(TooltipContext);
11
+
12
+ if (context === null) {
13
+ throw new Error('Tooltip components must be wrapped in <Tooltip />');
14
+ }
15
+
16
+ return context;
17
+ };
@@ -1 +1 @@
1
- export { default as useTooltip } from './useTooltip';
1
+ export { Tooltip } from './Tooltip';
@@ -0,0 +1,54 @@
1
+ import {
2
+ Placement,
3
+ arrow,
4
+ autoUpdate,
5
+ flip,
6
+ offset,
7
+ shift,
8
+ useDelayGroup,
9
+ useDismiss,
10
+ useFloating,
11
+ useFocus,
12
+ useHover,
13
+ useInteractions,
14
+ useRole,
15
+ } from '@floating-ui/react';
16
+ import { useMemo, useRef, useState } from 'react';
17
+
18
+ const ARROW_SIZE = 7;
19
+ const ARROW_GAP = 3;
20
+ const PADDING = 10;
21
+
22
+ interface TooltipOptions {
23
+ placement?: Placement;
24
+ }
25
+
26
+ export const useTooltip = ({ placement = 'top' }: TooltipOptions = {}) => {
27
+ const [isOpen, setIsOpen] = useState(false);
28
+ const arrowRef = useRef(null);
29
+ const data = useFloating({
30
+ placement,
31
+ open: isOpen,
32
+ onOpenChange: setIsOpen,
33
+ whileElementsMounted: autoUpdate,
34
+ middleware: [flip(), shift({ padding: PADDING }), offset(ARROW_SIZE + ARROW_GAP), arrow({ element: arrowRef })],
35
+ });
36
+ const { context } = data;
37
+ const { delay } = useDelayGroup(context);
38
+ const hover = useHover(context, { move: false, delay });
39
+ const focus = useFocus(context);
40
+ const dismiss = useDismiss(context);
41
+ const role = useRole(context, { role: 'tooltip' });
42
+ const interactions = useInteractions([hover, focus, dismiss, role]);
43
+
44
+ return useMemo(
45
+ () => ({
46
+ arrowRef,
47
+ open: isOpen,
48
+ setOpen: setIsOpen,
49
+ ...interactions,
50
+ ...data,
51
+ }),
52
+ [arrowRef, isOpen, setIsOpen, interactions, data],
53
+ );
54
+ };
@@ -2,7 +2,6 @@ export { default as Alert } from './Alert';
2
2
  export { default as Badge } from './Badge';
3
3
  export { default as Board } from './Board';
4
4
  export { default as Button } from './Button';
5
- export { default as Checkbox } from './Checkbox';
6
5
  export { default as Dictionary } from './Dictionary';
7
6
  export { default as DictionaryInput } from './DictionaryInput';
8
7
  export { default as EmptyState } from './EmptyState';
@@ -23,4 +22,4 @@ export { default as SeoMessage } from './SeoMessage';
23
22
  export { default as Solver } from './Solver';
24
23
  export { default as Spinner } from './Spinner';
25
24
  export { default as Tile } from './Tile';
26
- export { useTooltip } from './Tooltip';
25
+ export * from './Tooltip';
@@ -9,5 +9,4 @@ export { default as useMedia } from './useMedia';
9
9
  export { default as useMediaQueries } from './useMediaQueries';
10
10
  export { default as useMediaQuery } from './useMediaQuery';
11
11
  export { default as useOnWindowResize } from './useOnWindowResize';
12
- export { default as usePortal } from './usePortal';
13
12
  export { default as useViewportSize } from './useViewportSize';
@@ -22,7 +22,7 @@
22
22
  "dictionary.empty-state.no-definitions": "Wort existiert im Wörterbuch aber hat keine Definition.",
23
23
  "dictionary.empty-state.no-results": "Wort kann nicht im Wörterbuch gefunden werden.",
24
24
  "dictionary.empty-state.not-allowed": "Dieses Wort ist nicht erlaubt.",
25
- "dictionary.empty-state.uninitialized": "Die Wörterbuchdéfinition wird hier angezeigt.",
25
+ "dictionary.empty-state.uninitialized": "Die Wörterbuchdefinition wird hier angezeigt.",
26
26
  "dictionary.input.placeholder": "Durchsuche Wörterbuch…",
27
27
  "dictionary.input.title": "Durch Kommas getrennte Wörter",
28
28
  "empty-state.error": "Fehler",
@@ -5,8 +5,6 @@ export { default as ArrowUp } from './ArrowUp.svg';
5
5
  export { default as BookHalf } from './BookHalf.svg';
6
6
  export { default as CardChecklist } from './CardChecklist.svg';
7
7
  export { default as Check } from './Check.svg';
8
- export { default as CheckboxChecked } from './CheckboxChecked.svg';
9
- export { default as CheckboxEmpty } from './CheckboxEmpty.svg';
10
8
  export { default as ChevronDown } from './ChevronDown.svg';
11
9
  export { default as ChevronLeft } from './ChevronLeft.svg';
12
10
  export { default as ChevronRight } from './ChevronRight.svg';
@@ -0,0 +1,18 @@
1
+ import { Result, ShowCoordinates } from '@scrabble-solver/types';
2
+
3
+ import getCoordinate from './getCoordinate';
4
+
5
+ const getCoordinates = (result: Result, showCoordinates: ShowCoordinates): string => {
6
+ if (showCoordinates === 'hidden') {
7
+ return '';
8
+ }
9
+
10
+ const firstCell = result.cells[0];
11
+ const isHorizontal = firstCell.x !== result.cells[1].x;
12
+ const x = getCoordinate(firstCell.x, showCoordinates === 'original' ? 'letter' : 'number');
13
+ const y = getCoordinate(firstCell.y, showCoordinates === 'original' ? 'number' : 'letter');
14
+
15
+ return isHorizontal ? `${y}${x}` : `${x}${y}`;
16
+ };
17
+
18
+ export default getCoordinates;
@@ -18,18 +18,23 @@ const groupResults = (
18
18
  return results;
19
19
  }
20
20
 
21
+ const regExp = createRegExp(query);
22
+
21
23
  return results.reduce<GroupedResults>(
22
- ({ matching, other }, result) => {
23
- const matchesQuery = createRegExp(query).test(result.word);
24
- const matchesCellFilter = cellFilter.every(({ x, y }) => {
25
- return result.cells.some((cell) => cell.x === x && cell.y === y);
26
- });
27
- const isMatching = matchesQuery && matchesCellFilter;
28
-
29
- return {
30
- matching: isMatching ? [...matching, result] : matching,
31
- other: isMatching ? other : [...other, result],
32
- };
24
+ (groupedResults, result) => {
25
+ const matchesQuery = () => regExp.test(result.word);
26
+ const matchesCellFilter = () =>
27
+ cellFilter.every(({ x, y }) => {
28
+ return result.cells.some((cell) => cell.x === x && cell.y === y);
29
+ });
30
+
31
+ if (matchesCellFilter() && matchesQuery()) {
32
+ groupedResults.matching.push(result);
33
+ } else {
34
+ groupedResults.other.push(result);
35
+ }
36
+
37
+ return groupedResults;
33
38
  },
34
39
  { matching: [], other: [] },
35
40
  );
@@ -1,5 +1,4 @@
1
1
  export { default as arrayEquals } from './arrayEquals';
2
- export { default as canUseDom } from './canUseDom';
3
2
  export { default as createArray } from './createArray';
4
3
  export { default as createComparator } from './createComparator';
5
4
  export { default as createGridOf } from './createGridOf';
@@ -15,6 +14,8 @@ export { default as extractCharactersByCase } from './extractCharactersByCase';
15
14
  export { default as extractInputValue } from './extractInputValue';
16
15
  export { default as findCell } from './findCell';
17
16
  export { default as getCellSize } from './getCellSize';
17
+ export { default as getCoordinate } from './getCoordinate';
18
+ export { default as getCoordinates } from './getCoordinates';
18
19
  export { default as getRemainingTiles } from './getRemainingTiles';
19
20
  export { default as getRemainingTilesCount } from './getRemainingTilesCount';
20
21
  export { default as getRemainingTilesGroups } from './getRemainingTilesGroups';
@@ -8,6 +8,7 @@ import reverseComparator from './reverseComparator';
8
8
  const comparators: Record<ResultColumn, (locale: string) => Comparator<Result>> = {
9
9
  [ResultColumn.BlanksCount]: (locale: string) => createKeyComparator('blanksCount', locale),
10
10
  [ResultColumn.ConsonantsCount]: (locale: string) => createKeyComparator('consonantsCount', locale),
11
+ [ResultColumn.Coordinates]: () => () => 0,
11
12
  [ResultColumn.Points]: (locale: string) => createKeyComparator('points', locale),
12
13
  [ResultColumn.TilesCount]: (locale: string) => createKeyComparator('tilesCount', locale),
13
14
  [ResultColumn.VowelsCount]: (locale: string) => createKeyComparator('vowelsCount', locale),
@@ -39,10 +39,10 @@
39
39
  }
40
40
 
41
41
  &:first-child {
42
- margin-left: 0;
42
+ margin-inline-start: 0;
43
43
  }
44
44
 
45
45
  &:last-child {
46
- margin-right: 0;
46
+ margin-inline-end: 0;
47
47
  }
48
48
  }
@@ -31,13 +31,7 @@
31
31
  --aspect-ratio: var(--highest-flag-aspect-ratio);
32
32
  --padding: calc(var(--spacing--l) + var(--button--icon--size) * var(--aspect-ratio));
33
33
 
34
- [dir='ltr'] & {
35
- padding-right: var(--padding);
36
- }
37
-
38
- [dir='rtl'] & {
39
- padding-left: var(--padding);
40
- }
34
+ padding-inline-end: var(--padding);
41
35
  }
42
36
 
43
37
  .flag {
@@ -45,12 +39,5 @@
45
39
  height: var(--button--icon--size);
46
40
  border-radius: var(--border--radius);
47
41
  box-shadow: 0 0 0 1px var(--box-shadow--color);
48
-
49
- [dir='ltr'] & {
50
- right: calc(2 * var(--spacing--l));
51
- }
52
-
53
- [dir='rtl'] & {
54
- left: calc(2 * var(--spacing--l));
55
- }
42
+ inset-inline-end: calc(2 * var(--spacing--l));
56
43
  }
@@ -12,13 +12,7 @@
12
12
  }
13
13
 
14
14
  .badge {
15
- [dir='ltr'] & {
16
- margin-left: var(--spacing--m);
17
- }
18
-
19
- [dir='rtl'] & {
20
- margin-right: var(--spacing--m);
21
- }
15
+ margin-inline-start: var(--spacing--m);
22
16
  }
23
17
 
24
18
  .character {
@@ -6,13 +6,7 @@
6
6
  }
7
7
 
8
8
  .badge {
9
- [dir='ltr'] & {
10
- margin-left: var(--spacing--m);
11
- }
12
-
13
- [dir='rtl'] & {
14
- margin-right: var(--spacing--m);
15
- }
9
+ margin-inline-start: var(--spacing--m);
16
10
  }
17
11
 
18
12
  .word {
@@ -37,12 +31,5 @@
37
31
 
38
32
  width: $size;
39
33
  height: $size;
40
-
41
- [dir='ltr'] & {
42
- margin-right: var(--spacing--s);
43
- }
44
-
45
- [dir='rtl'] & {
46
- margin-left: var(--spacing--s);
47
- }
34
+ margin-inline-end: var(--spacing--s);
48
35
  }
@@ -1,3 +1,4 @@
1
+ import { FloatingDelayGroup } from '@floating-ui/react';
1
2
  import { AppProps } from 'next/app';
2
3
  import Head from 'next/head';
3
4
  import { FunctionComponent } from 'react';
@@ -64,7 +65,10 @@ const App: FunctionComponent<AppProps> = ({ Component, pageProps }) => (
64
65
 
65
66
  <Provider store={store}>
66
67
  <SeoMessage />
67
- <Component {...pageProps} />
68
+
69
+ <FloatingDelayGroup delay={0}>
70
+ <Component {...pageProps} />
71
+ </FloatingDelayGroup>
68
72
  </Provider>
69
73
  </>
70
74
  );
@@ -90,6 +90,7 @@ export const MODAL_HEADER_HEIGHT = 45;
90
90
  export const NAV_PADDING = SPACING_L;
91
91
 
92
92
  export const TILE_SIZE = 80;
93
+ export const TOOLTIP_DURATION = TRANSITION_DURATION;
93
94
 
94
95
  export const PLAIN_TILES_COLOR_DEFAULT = COLOR_GREEN;
95
96
  export const PLAIN_TILES_PADDING_HORIZONTAL = 0;
@@ -14,7 +14,7 @@ $media-expressions: (
14
14
 
15
15
  @mixin scrollbars {
16
16
  scrollbar-color: var(--scrollbar--thumb--color) var(--scrollbar--thumb--track);
17
- scrollbar-width: auto;
17
+ scrollbar-width: thin;
18
18
 
19
19
  &::-webkit-scrollbar {
20
20
  width: var(--scrollbar--size);
@@ -44,10 +44,7 @@ $media-expressions: (
44
44
 
45
45
  &::after {
46
46
  position: absolute;
47
- top: 0;
48
- right: 0;
49
- bottom: 0;
50
- left: 0;
47
+ inset: 0;
51
48
  z-index: var(--z-index--focus-effect);
52
49
  transition: var(--transition);
53
50
  border-radius: var(--border--radius);
@@ -40,6 +40,7 @@ export interface RemainingTilesGroup {
40
40
  export enum ResultColumn {
41
41
  BlanksCount = 'blanks-count',
42
42
  ConsonantsCount = 'consonants-count',
43
+ Coordinates = 'coordinates',
43
44
  Points = 'points',
44
45
  TilesCount = 'tiles-count',
45
46
  VowelsCount = 'vowels-count',
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@scrabble-solver/solver",
3
- "version": "2.13.6",
3
+ "version": "2.13.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/solver",
9
- "version": "2.13.6",
9
+ "version": "2.13.8",
10
10
  "license": "CC-BY-NC-ND-4.0",
11
11
  "dependencies": {
12
12
  "@kamilmielnik/trie": "^3.0.0"