@scrabble-solver/scrabble-solver 2.11.0 → 2.11.1
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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +7 -7
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/eslint/.cache_8dgz12 +1 -1
- package/.next/cache/next-server.js.nft.json +1 -1
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/277.js +341 -459
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/404.js.nft.json +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_app.js +0 -24
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/api/solve.js +0 -1
- package/.next/server/pages/index.html +1 -1
- package/.next/server/pages/index.js +4 -52
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/index.json +1 -1
- package/.next/static/chunks/pages/{404-e0f30450e9920dc3.js → 404-448ba28510855455.js} +1 -1
- package/.next/static/chunks/pages/_app-270526803bc274eb.js +28 -0
- package/.next/static/chunks/pages/index-c6e7754ccf3532df.js +1 -0
- package/.next/static/css/ad39b36eab07e613.css +1 -0
- package/.next/static/css/e5803e581e4c0451.css +2 -0
- package/.next/static/esK8DG-6aS5V7QFRtR3YE/_buildManifest.js +1 -0
- package/.next/trace +53 -55
- package/package.json +9 -14
- package/src/components/{Solver/components/EmptyState/EmptyState.module.scss → Alert/Alert.module.scss} +11 -7
- package/src/components/{Solver/components/EmptyState/EmptyState.tsx → Alert/Alert.tsx} +8 -6
- package/src/components/Alert/index.ts +1 -0
- package/src/components/Board/Board.module.scss +55 -0
- package/src/components/Board/BoardPure.tsx +4 -0
- package/src/components/Board/components/Cell/Cell.module.scss +41 -0
- package/src/components/Board/components/Cell/Cell.tsx +12 -0
- package/src/components/Board/components/Cell/CellPure.tsx +12 -0
- package/src/components/Board/hooks/useGrid.ts +8 -24
- package/src/components/Dictionary/Dictionary.module.scss +4 -0
- package/src/components/DictionaryInput/DictionaryInput.module.scss +1 -0
- package/src/components/EmptyState/EmptyState.module.scss +2 -1
- package/src/components/EmptyState/EmptyState.tsx +1 -2
- package/src/components/Loading/Loading.module.scss +1 -1
- package/src/components/Logo/Logo.tsx +5 -0
- package/src/components/Modal/Modal.module.scss +2 -0
- package/src/components/PlainTiles/PlainTiles.module.scss +1 -1
- package/src/components/PlainTiles/Tile.tsx +3 -3
- package/src/components/Rack/Rack.module.scss +25 -0
- package/src/components/Rack/Rack.tsx +5 -4
- package/src/components/Rack/RackTile.tsx +6 -13
- package/src/components/Results/Results.module.scss +28 -0
- package/src/components/ResultsInput/ResultsInput.module.scss +1 -0
- package/src/components/Solver/Solver.module.scss +5 -4
- package/src/components/Solver/Solver.tsx +8 -7
- package/src/components/Solver/components/index.ts +0 -1
- package/src/components/Tile/Tile.module.scss +14 -2
- package/src/components/Tooltip/Tooltip.module.scss +1 -72
- package/src/components/Tooltip/useTooltip.tsx +25 -35
- package/src/components/index.ts +1 -0
- package/src/hooks/index.ts +0 -1
- package/src/lib/index.ts +0 -1
- package/src/modals/DictionaryModal/DictionaryModal.module.scss +6 -1
- package/src/modals/KeyMapModal/KeyMapModal.tsx +5 -21
- package/src/modals/KeyMapModal/components/Mapping/Mapping.module.scss +4 -0
- package/src/modals/RemainingTilesModal/components/Character/Character.module.scss +1 -0
- package/src/modals/ResultsModal/ResultsModal.module.scss +1 -0
- package/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.module.scss +2 -0
- package/src/modals/WordsModal/WordsModal.module.scss +8 -1
- package/src/state/createAppStore.ts +26 -10
- package/src/state/types.ts +20 -2
- package/src/styles/mixins.scss +22 -0
- package/src/styles/variables.scss +16 -1
- package/.next/static/45ye7793DY705HOcuK9lJ/_buildManifest.js +0 -1
- package/.next/static/chunks/pages/_app-d7acee5e526752d9.js +0 -28
- package/.next/static/chunks/pages/index-35d2c1c79a201ae2.js +0 -1
- package/.next/static/css/a48caa6f57de6e98.css +0 -1
- package/.next/static/css/c49bbe944ddd1b39.css +0 -2
- package/src/components/Solver/components/EmptyState/index.ts +0 -1
- package/src/components/Tooltip/constants.ts +0 -28
- package/src/hooks/useUniqueId.ts +0 -9
- package/src/lib/isCtrl.ts +0 -7
- package/src/state/rootReducer.ts +0 -25
- /package/.next/static/{45ye7793DY705HOcuK9lJ → esK8DG-6aS5V7QFRtR3YE}/_ssgManifest.js +0 -0
|
@@ -9,6 +9,7 @@ $row-padding-horizontal: calc(var(--spacing--m) + var(--spacing--s));
|
|
|
9
9
|
height: 100%;
|
|
10
10
|
background: var(--color--background--element);
|
|
11
11
|
border: var(--border);
|
|
12
|
+
border-radius: var(--border--radius);
|
|
12
13
|
box-shadow: var(--box-shadow);
|
|
13
14
|
font-family: var(--font--family--title);
|
|
14
15
|
}
|
|
@@ -29,6 +30,9 @@ $row-padding-horizontal: calc(var(--spacing--m) + var(--spacing--s));
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
.list {
|
|
33
|
+
@include scrollbars;
|
|
34
|
+
|
|
35
|
+
scrollbar-gutter: stable;
|
|
32
36
|
transition: var(--transition);
|
|
33
37
|
|
|
34
38
|
&.outdated {
|
|
@@ -44,6 +48,8 @@ $row-padding-horizontal: calc(var(--spacing--m) + var(--spacing--s));
|
|
|
44
48
|
justify-content: space-between;
|
|
45
49
|
font-weight: 700;
|
|
46
50
|
border-bottom: var(--border);
|
|
51
|
+
border-top-left-radius: inherit;
|
|
52
|
+
border-top-right-radius: inherit;
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
.headerButton {
|
|
@@ -60,6 +66,26 @@ $row-padding-horizontal: calc(var(--spacing--m) + var(--spacing--s));
|
|
|
60
66
|
background-color: var(--color--primary);
|
|
61
67
|
color: var(--color--primary--opposite);
|
|
62
68
|
}
|
|
69
|
+
|
|
70
|
+
&:first-child {
|
|
71
|
+
[dir='ltr'] & {
|
|
72
|
+
border-top-left-radius: inherit;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
[dir='rtl'] & {
|
|
76
|
+
border-top-right-radius: inherit;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&:last-child {
|
|
81
|
+
[dir='ltr'] & {
|
|
82
|
+
border-top-right-radius: inherit;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
[dir='rtl'] & {
|
|
86
|
+
border-top-left-radius: inherit;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
63
89
|
}
|
|
64
90
|
|
|
65
91
|
.headerButtonLabel {
|
|
@@ -175,4 +201,6 @@ $row-padding-horizontal: calc(var(--spacing--m) + var(--spacing--s));
|
|
|
175
201
|
|
|
176
202
|
.input {
|
|
177
203
|
border-top: var(--border);
|
|
204
|
+
border-bottom-left-radius: var(--border--radius);
|
|
205
|
+
border-bottom-right-radius: var(--border--radius);
|
|
178
206
|
}
|
|
@@ -70,16 +70,21 @@
|
|
|
70
70
|
flex-direction: column;
|
|
71
71
|
background-color: var(--color--background--element);
|
|
72
72
|
border: var(--border);
|
|
73
|
+
border-radius: var(--border--radius);
|
|
73
74
|
box-shadow: var(--box-shadow);
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
.dictionary {
|
|
77
78
|
flex: 1;
|
|
78
79
|
border-bottom: var(--border);
|
|
80
|
+
border-top-left-radius: var(--border--radius);
|
|
81
|
+
border-top-right-radius: var(--border--radius);
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
.dictionaryInput {
|
|
82
85
|
flex: 0 0 auto;
|
|
86
|
+
border-bottom-left-radius: var(--border--radius);
|
|
87
|
+
border-bottom-right-radius: var(--border--radius);
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
.bottomContainer {
|
|
@@ -97,10 +102,6 @@
|
|
|
97
102
|
min-width: 0;
|
|
98
103
|
}
|
|
99
104
|
|
|
100
|
-
.rack {
|
|
101
|
-
border: var(--border);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
105
|
.controls {
|
|
105
106
|
width: 100%;
|
|
106
107
|
}
|
|
@@ -19,13 +19,14 @@ import {
|
|
|
19
19
|
useTypedSelector,
|
|
20
20
|
} from 'state';
|
|
21
21
|
|
|
22
|
+
import Alert from '../Alert';
|
|
22
23
|
import Board from '../Board';
|
|
23
24
|
import Dictionary from '../Dictionary';
|
|
24
25
|
import DictionaryInput from '../DictionaryInput';
|
|
25
26
|
import Rack from '../Rack';
|
|
26
27
|
import Results from '../Results';
|
|
27
28
|
|
|
28
|
-
import {
|
|
29
|
+
import { FloatingSolveButton, ResultCandidatePicker } from './components';
|
|
29
30
|
import styles from './Solver.module.scss';
|
|
30
31
|
|
|
31
32
|
interface Props {
|
|
@@ -111,7 +112,7 @@ const Solver: FunctionComponent<Props> = ({ className, height, width, onShowResu
|
|
|
111
112
|
<div className={classNames(styles.solver, className)}>
|
|
112
113
|
<div className={styles.container}>
|
|
113
114
|
<div className={styles.content}>
|
|
114
|
-
<form
|
|
115
|
+
<form className={styles.boardContainer} onSubmit={handleSubmit}>
|
|
115
116
|
<Board cellSize={cellSizeSafe} className={styles.board} />
|
|
116
117
|
<input className={styles.submitInput} tabIndex={-1} type="submit" />
|
|
117
118
|
</form>
|
|
@@ -129,7 +130,7 @@ const Solver: FunctionComponent<Props> = ({ className, height, width, onShowResu
|
|
|
129
130
|
|
|
130
131
|
<div className={styles.bottomContainer} ref={bottomContainerRef}>
|
|
131
132
|
<div className={styles.bottomContent}>
|
|
132
|
-
<form
|
|
133
|
+
<form onSubmit={handleSubmit}>
|
|
133
134
|
<Rack className={styles.rack} tileSize={tileSize} />
|
|
134
135
|
<input className={styles.submitInput} tabIndex={-1} type="submit" />
|
|
135
136
|
</form>
|
|
@@ -139,15 +140,15 @@ const Solver: FunctionComponent<Props> = ({ className, height, width, onShowResu
|
|
|
139
140
|
<ResultCandidatePicker onResultClick={onShowResults} />
|
|
140
141
|
|
|
141
142
|
{error && (
|
|
142
|
-
<
|
|
143
|
+
<Alert className={styles.emptyState} variant="error">
|
|
143
144
|
{error.message}
|
|
144
|
-
</
|
|
145
|
+
</Alert>
|
|
145
146
|
)}
|
|
146
147
|
|
|
147
148
|
{allResults && allResults.length === 0 && !isOutdated && (
|
|
148
|
-
<
|
|
149
|
+
<Alert className={styles.emptyState} variant="warning">
|
|
149
150
|
{translate('results.empty-state.no-results')}
|
|
150
|
-
</
|
|
151
|
+
</Alert>
|
|
151
152
|
)}
|
|
152
153
|
</div>
|
|
153
154
|
)}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
position: relative;
|
|
7
7
|
transition: var(--transition);
|
|
8
|
+
border-radius: var(--border--radius);
|
|
8
9
|
|
|
9
10
|
&.points1 {
|
|
10
11
|
--background-color: var(--color--yellow);
|
|
@@ -85,6 +86,7 @@
|
|
|
85
86
|
align-items: center;
|
|
86
87
|
justify-content: center;
|
|
87
88
|
background-color: var(--background-color);
|
|
89
|
+
border-radius: inherit;
|
|
88
90
|
transition: var(--transition);
|
|
89
91
|
pointer-events: none;
|
|
90
92
|
user-select: none;
|
|
@@ -94,10 +96,18 @@
|
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
.raised & {
|
|
97
|
-
|
|
99
|
+
--shadow--size: 2px;
|
|
100
|
+
--shadow--blur: 2px;
|
|
101
|
+
--shadow--spread: -1px;
|
|
102
|
+
--shadow--color: rgba(34, 34, 34, 0.8);
|
|
103
|
+
|
|
104
|
+
box-shadow: inset calc(-1 * var(--shadow--size)) calc(-1 * var(--shadow--size)) var(--shadow--blur)
|
|
105
|
+
var(--shadow--spread) var(--shadow--color);
|
|
98
106
|
|
|
99
107
|
@include media('<xs') {
|
|
100
|
-
|
|
108
|
+
--shadow--size: 1px;
|
|
109
|
+
--shadow--spread: 0;
|
|
110
|
+
--shadow--blur: 1px;
|
|
101
111
|
}
|
|
102
112
|
}
|
|
103
113
|
}
|
|
@@ -146,10 +156,12 @@
|
|
|
146
156
|
[dir='ltr'] & {
|
|
147
157
|
top: 0;
|
|
148
158
|
right: 0;
|
|
159
|
+
border-top-right-radius: inherit;
|
|
149
160
|
}
|
|
150
161
|
|
|
151
162
|
[dir='rtl'] & {
|
|
152
163
|
bottom: 0;
|
|
153
164
|
right: 0;
|
|
165
|
+
border-bottom-right-radius: inherit;
|
|
154
166
|
}
|
|
155
167
|
}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
$arrow-size: 4px;
|
|
2
|
-
|
|
3
|
-
:export {
|
|
4
|
-
ARROW_SIZE: $arrow-size;
|
|
5
|
-
PREVENT_OVERFLOW: 10px;
|
|
6
|
-
OFFSET: 2px;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
1
|
.tooltip {
|
|
10
2
|
padding: var(--spacing--s) var(--spacing--m);
|
|
11
3
|
box-shadow: var(--box-shadow);
|
|
@@ -13,71 +5,8 @@ $arrow-size: 4px;
|
|
|
13
5
|
background-color: var(--color--tooltip--background);
|
|
14
6
|
color: var(--color--tooltip--foreground);
|
|
15
7
|
z-index: var(--z-index--tooltip);
|
|
16
|
-
|
|
17
|
-
&.top {
|
|
18
|
-
.arrow {
|
|
19
|
-
bottom: -$arrow-size;
|
|
20
|
-
|
|
21
|
-
&::after {
|
|
22
|
-
left: 0;
|
|
23
|
-
bottom: 0;
|
|
24
|
-
border-top-color: var(--color--tooltip--background);
|
|
25
|
-
border-bottom: none;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
&.right {
|
|
31
|
-
.arrow {
|
|
32
|
-
left: -$arrow-size;
|
|
33
|
-
|
|
34
|
-
&::after {
|
|
35
|
-
left: 0;
|
|
36
|
-
top: 0;
|
|
37
|
-
border-right-color: var(--color--tooltip--background);
|
|
38
|
-
border-left: none;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
&.bottom {
|
|
44
|
-
.arrow {
|
|
45
|
-
top: -$arrow-size;
|
|
46
|
-
|
|
47
|
-
&::after {
|
|
48
|
-
top: 0;
|
|
49
|
-
left: 0;
|
|
50
|
-
border-bottom-color: var(--color--tooltip--background);
|
|
51
|
-
border-top: none;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
&.left {
|
|
57
|
-
.arrow {
|
|
58
|
-
right: -$arrow-size;
|
|
59
|
-
|
|
60
|
-
&::after {
|
|
61
|
-
right: 0;
|
|
62
|
-
top: 0;
|
|
63
|
-
border-left-color: var(--color--tooltip--background);
|
|
64
|
-
border-right: none;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
8
|
}
|
|
69
9
|
|
|
70
10
|
.arrow {
|
|
71
|
-
|
|
72
|
-
width: 2 * $arrow-size;
|
|
73
|
-
height: 2 * $arrow-size;
|
|
74
|
-
|
|
75
|
-
&::after {
|
|
76
|
-
content: ' ';
|
|
77
|
-
position: absolute;
|
|
78
|
-
height: 0;
|
|
79
|
-
width: 0;
|
|
80
|
-
pointer-events: none;
|
|
81
|
-
border: $arrow-size solid transparent;
|
|
82
|
-
}
|
|
11
|
+
fill: var(--color--tooltip--background);
|
|
83
12
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { arrow, autoUpdate, flip, FloatingArrow, offset, shift, useFloating } from '@floating-ui/react';
|
|
1
2
|
import classNames from 'classnames';
|
|
2
3
|
import {
|
|
3
4
|
FocusEvent,
|
|
@@ -6,16 +7,15 @@ import {
|
|
|
6
7
|
MouseEventHandler,
|
|
7
8
|
ReactNode,
|
|
8
9
|
useCallback,
|
|
10
|
+
useId,
|
|
9
11
|
useMemo,
|
|
12
|
+
useRef,
|
|
10
13
|
useState,
|
|
11
14
|
} from 'react';
|
|
12
|
-
import { usePopper } from 'react-popper';
|
|
13
|
-
import { useMountedState, useRafLoop } from 'react-use';
|
|
14
15
|
|
|
15
|
-
import { useIsTouchDevice, usePortal
|
|
16
|
+
import { useIsTouchDevice, usePortal } from 'hooks';
|
|
16
17
|
import { noop } from 'lib';
|
|
17
18
|
|
|
18
|
-
import { MODIFIERS } from './constants';
|
|
19
19
|
import styles from './Tooltip.module.scss';
|
|
20
20
|
|
|
21
21
|
interface Props {
|
|
@@ -36,29 +36,27 @@ interface TriggerProps {
|
|
|
36
36
|
onMouseOver?: MouseEventHandler;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
const ARROW_SIZE = 7;
|
|
40
|
+
const ARROW_GAP = 3;
|
|
41
|
+
const PADDING = 10;
|
|
42
|
+
|
|
39
43
|
// eslint-disable-next-line max-statements
|
|
40
44
|
const useTooltip = (
|
|
41
45
|
tooltip: ReactNode,
|
|
42
46
|
{ className, placement = 'top', onBlur = noop, onFocus = noop, onMouseOut = noop, onMouseOver = noop }: Props = {},
|
|
43
47
|
): TriggerProps => {
|
|
44
|
-
const id =
|
|
48
|
+
const id = useId();
|
|
45
49
|
const isTouchDevice = useIsTouchDevice();
|
|
46
50
|
const isEnabled = Boolean(tooltip) || tooltip === 0;
|
|
47
|
-
const isMounted = useMountedState();
|
|
48
51
|
const [isShown, setIsShown] = useState<boolean>(false);
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
const {
|
|
53
|
-
|
|
54
|
-
styles: popperStyles,
|
|
55
|
-
update,
|
|
56
|
-
} = usePopper(referenceElement, popperElement, {
|
|
57
|
-
modifiers: [{ name: 'arrow', options: { element: arrowElement } }, ...MODIFIERS],
|
|
52
|
+
const arrowRef = useRef(null);
|
|
53
|
+
const ariaAttributes = useMemo(() => (isShown ? { 'aria-describedby': id } : {}), [id, isShown]);
|
|
54
|
+
|
|
55
|
+
const { x, y, context, refs, strategy } = useFloating({
|
|
56
|
+
middleware: [flip(), shift({ padding: PADDING }), offset(ARROW_SIZE + ARROW_GAP), arrow({ element: arrowRef })],
|
|
58
57
|
placement,
|
|
58
|
+
whileElementsMounted: autoUpdate,
|
|
59
59
|
});
|
|
60
|
-
const computedPlacement = attributes.popper ? attributes.popper['data-popper-placement'] : placement;
|
|
61
|
-
const ariaAttributes = useMemo(() => (isShown ? { 'aria-describedby': id } : {}), [id, isShown]);
|
|
62
60
|
|
|
63
61
|
const handleBlur = useCallback(
|
|
64
62
|
(event: FocusEvent) => {
|
|
@@ -95,7 +93,7 @@ const useTooltip = (
|
|
|
95
93
|
const mouseTriggerProps = useMemo(
|
|
96
94
|
() => ({
|
|
97
95
|
...ariaAttributes,
|
|
98
|
-
ref:
|
|
96
|
+
ref: refs.setReference,
|
|
99
97
|
onBlur: handleBlur,
|
|
100
98
|
onFocus: handleFocus,
|
|
101
99
|
onMouseOut: handleMouseOut,
|
|
@@ -107,33 +105,25 @@ const useTooltip = (
|
|
|
107
105
|
const touchTriggerProps = useMemo(
|
|
108
106
|
() => ({
|
|
109
107
|
...ariaAttributes,
|
|
110
|
-
ref:
|
|
108
|
+
ref: refs.setReference,
|
|
111
109
|
}),
|
|
112
110
|
[ariaAttributes],
|
|
113
111
|
);
|
|
114
112
|
|
|
115
113
|
const triggerProps = isTouchDevice ? touchTriggerProps : mouseTriggerProps;
|
|
116
114
|
|
|
117
|
-
useRafLoop(() => {
|
|
118
|
-
if (isMounted() && update) {
|
|
119
|
-
update();
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
|
|
123
115
|
usePortal(
|
|
124
116
|
<div
|
|
125
|
-
className={classNames(styles.tooltip, className
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
style={popperStyles.popper}
|
|
133
|
-
{...attributes.popper}
|
|
117
|
+
className={classNames(styles.tooltip, className)}
|
|
118
|
+
ref={refs.setFloating}
|
|
119
|
+
style={{
|
|
120
|
+
position: strategy,
|
|
121
|
+
top: y ?? 0,
|
|
122
|
+
left: x ?? 0,
|
|
123
|
+
}}
|
|
134
124
|
>
|
|
135
125
|
<div>{tooltip}</div>
|
|
136
|
-
<
|
|
126
|
+
<FloatingArrow className={styles.arrow} context={context} ref={arrowRef} />
|
|
137
127
|
</div>,
|
|
138
128
|
{ disabled: !isEnabled || !isShown },
|
|
139
129
|
);
|
package/src/components/index.ts
CHANGED
package/src/hooks/index.ts
CHANGED
|
@@ -5,4 +5,3 @@ export { default as useLanguage } from './useLanguage';
|
|
|
5
5
|
export { default as useLocalStorage } from './useLocalStorage';
|
|
6
6
|
export { default as useMediaQuery } from './useMediaQuery';
|
|
7
7
|
export { default as usePortal } from './usePortal';
|
|
8
|
-
export { default as useUniqueId } from './useUniqueId';
|
package/src/lib/index.ts
CHANGED
|
@@ -17,7 +17,6 @@ export { default as getRemainingTilesGroups } from './getRemainingTilesGroups';
|
|
|
17
17
|
export { default as getTotalRemainingTilesCount } from './getTotalRemainingTilesCount';
|
|
18
18
|
export { default as getTileSizes } from './getTileSizes';
|
|
19
19
|
export { default as inverseDirection } from './inverseDirection';
|
|
20
|
-
export { default as isCtrl } from './isCtrl';
|
|
21
20
|
export { default as isMac } from './isMac';
|
|
22
21
|
export { default as isRegExp } from './isRegExp';
|
|
23
22
|
export { default as isStringArray } from './isStringArray';
|
|
@@ -4,15 +4,20 @@
|
|
|
4
4
|
flex-direction: column;
|
|
5
5
|
background-color: var(--color--background--element);
|
|
6
6
|
border: var(--border);
|
|
7
|
+
border-radius: var(--border--radius);
|
|
7
8
|
box-shadow: var(--box-shadow);
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
.dictionary {
|
|
11
12
|
flex: 1;
|
|
12
|
-
border-bottom: var(--border);
|
|
13
13
|
max-height: initial;
|
|
14
|
+
border-bottom: var(--border);
|
|
15
|
+
border-top-left-radius: var(--border--radius);
|
|
16
|
+
border-top-right-radius: var(--border--radius);
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
.dictionaryInput {
|
|
17
20
|
flex: 0 0 auto;
|
|
21
|
+
border-bottom-left-radius: var(--border--radius);
|
|
22
|
+
border-bottom-right-radius: var(--border--radius);
|
|
18
23
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FunctionComponent } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { Modal } from 'components';
|
|
4
|
+
import { useTranslate } from 'state';
|
|
5
5
|
|
|
6
6
|
import { Mapping } from './components';
|
|
7
|
-
import { ARROWS, BACKSPACE,
|
|
7
|
+
import { ARROWS, BACKSPACE, DEL, ENTER, SPACE } from './keys';
|
|
8
8
|
|
|
9
9
|
interface Props {
|
|
10
10
|
className?: string;
|
|
@@ -14,7 +14,6 @@ interface Props {
|
|
|
14
14
|
|
|
15
15
|
const KeyMapModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) => {
|
|
16
16
|
const translate = useTranslate();
|
|
17
|
-
const config = useTypedSelector(selectConfig);
|
|
18
17
|
|
|
19
18
|
return (
|
|
20
19
|
<Modal className={className} isOpen={isOpen} title={translate('keyMap')} onClose={onClose}>
|
|
@@ -22,26 +21,11 @@ const KeyMapModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =
|
|
|
22
21
|
<Mapping description={translate('keyMap.board-and-rack.navigate')} mapping={[ARROWS]} />
|
|
23
22
|
<Mapping description={translate('keyMap.board-and-rack.remove-tile')} mapping={[DEL, BACKSPACE]} />
|
|
24
23
|
<Mapping description={translate('keyMap.board-and-rack.submit')} mapping={[ENTER]} />
|
|
25
|
-
{config.twoCharacterTiles.length > 0 && (
|
|
26
|
-
<Mapping
|
|
27
|
-
description={translate('keyMap.board-and-rack.insert-two-letter-tile')}
|
|
28
|
-
mapping={[
|
|
29
|
-
[
|
|
30
|
-
CTRL,
|
|
31
|
-
<>
|
|
32
|
-
{config.twoCharacterTiles.map(([firstLetter]) => (
|
|
33
|
-
<Key key={firstLetter}>{firstLetter.toUpperCase()}</Key>
|
|
34
|
-
))}
|
|
35
|
-
</>,
|
|
36
|
-
],
|
|
37
|
-
]}
|
|
38
|
-
/>
|
|
39
|
-
)}
|
|
40
24
|
</Modal.Section>
|
|
41
25
|
|
|
42
26
|
<Modal.Section title={translate('keyMap.board')}>
|
|
43
|
-
<Mapping description={translate('keyMap.board.toggle-blank')} mapping={[SPACE
|
|
44
|
-
<Mapping description={translate('keyMap.board.toggle-direction')} mapping={[
|
|
27
|
+
<Mapping description={translate('keyMap.board.toggle-blank')} mapping={[SPACE]} />
|
|
28
|
+
<Mapping description={translate('keyMap.board.toggle-direction')} mapping={[ARROWS]} />
|
|
45
29
|
</Modal.Section>
|
|
46
30
|
|
|
47
31
|
<Modal.Section title={translate('keyMap.rack')}>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
flex: 0 0 calc(var(--dictionary--height) - var(--text-input--height));
|
|
17
17
|
background-color: var(--color--background--element);
|
|
18
18
|
border: var(--border);
|
|
19
|
+
border-radius: var(--border--radius);
|
|
19
20
|
box-shadow: var(--box-shadow);
|
|
20
21
|
|
|
21
22
|
@media (max-height: 600px) {
|
|
@@ -1,21 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { configureStore } from '@reduxjs/toolkit';
|
|
2
2
|
import reduxSaga from 'redux-saga';
|
|
3
3
|
|
|
4
|
-
import rootReducer from './rootReducer';
|
|
5
4
|
import { rootSaga } from './sagas';
|
|
6
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
boardSlice,
|
|
7
|
+
cellFilterSlice,
|
|
8
|
+
dictionarySlice,
|
|
9
|
+
rackSlice,
|
|
10
|
+
resultsSlice,
|
|
11
|
+
settingsSlice,
|
|
12
|
+
solveSlice,
|
|
13
|
+
verifySlice,
|
|
14
|
+
} from './slices';
|
|
7
15
|
|
|
8
16
|
const sagaMiddleware = reduxSaga();
|
|
9
|
-
const initialState: Partial<RootState> | undefined = undefined;
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
const createAppStore = () => {
|
|
19
|
+
const store = configureStore({
|
|
20
|
+
reducer: {
|
|
21
|
+
board: boardSlice.reducer,
|
|
22
|
+
cellFilter: cellFilterSlice.reducer,
|
|
23
|
+
dictionary: dictionarySlice.reducer,
|
|
24
|
+
rack: rackSlice.reducer,
|
|
25
|
+
results: resultsSlice.reducer,
|
|
26
|
+
settings: settingsSlice.reducer,
|
|
27
|
+
solve: solveSlice.reducer,
|
|
28
|
+
verify: verifySlice.reducer,
|
|
29
|
+
},
|
|
30
|
+
middleware: [sagaMiddleware],
|
|
31
|
+
});
|
|
15
32
|
|
|
16
|
-
const createAppStore = (): ReturnType<typeof createStore> => {
|
|
17
|
-
const store = createStore(rootReducer, initialState, composeEnhancers(applyMiddleware(sagaMiddleware)));
|
|
18
33
|
sagaMiddleware.run(rootSaga);
|
|
34
|
+
|
|
19
35
|
return store;
|
|
20
36
|
};
|
|
21
37
|
|
package/src/state/types.ts
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
boardSlice,
|
|
3
|
+
cellFilterSlice,
|
|
4
|
+
dictionarySlice,
|
|
5
|
+
rackSlice,
|
|
6
|
+
resultsSlice,
|
|
7
|
+
settingsSlice,
|
|
8
|
+
solveSlice,
|
|
9
|
+
verifySlice,
|
|
10
|
+
} from './slices';
|
|
2
11
|
|
|
3
|
-
export type RootState =
|
|
12
|
+
export type RootState = {
|
|
13
|
+
board: ReturnType<typeof boardSlice.reducer>;
|
|
14
|
+
cellFilter: ReturnType<typeof cellFilterSlice.reducer>;
|
|
15
|
+
dictionary: ReturnType<typeof dictionarySlice.reducer>;
|
|
16
|
+
rack: ReturnType<typeof rackSlice.reducer>;
|
|
17
|
+
results: ReturnType<typeof resultsSlice.reducer>;
|
|
18
|
+
settings: ReturnType<typeof settingsSlice.reducer>;
|
|
19
|
+
solve: ReturnType<typeof solveSlice.reducer>;
|
|
20
|
+
verify: ReturnType<typeof verifySlice.reducer>;
|
|
21
|
+
};
|
package/src/styles/mixins.scss
CHANGED
|
@@ -12,6 +12,28 @@ $media-expressions: (
|
|
|
12
12
|
touch: '(hover: none)',
|
|
13
13
|
);
|
|
14
14
|
|
|
15
|
+
@mixin scrollbars {
|
|
16
|
+
scrollbar-color: var(--scrollbar--thumb--color) var(--scrollbar--thumb--track);
|
|
17
|
+
scrollbar-width: auto;
|
|
18
|
+
|
|
19
|
+
&::-webkit-scrollbar {
|
|
20
|
+
width: var(--scrollbar--size);
|
|
21
|
+
background-color: var(--scrollbar--track--color);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&::-webkit-scrollbar-thumb {
|
|
25
|
+
background-color: var(--scrollbar--thumb--color);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&:hover {
|
|
29
|
+
scrollbar-color: var(--scrollbar--thumb--color--highlight) var(--scrollbar--track--color);
|
|
30
|
+
|
|
31
|
+
&::-webkit-scrollbar-thumb {
|
|
32
|
+
background-color: var(--scrollbar--thumb--color--highlight);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
15
37
|
/**
|
|
16
38
|
* It does not work when applied on input elements.
|
|
17
39
|
*/
|