@scrabble-solver/scrabble-solver 2.16.7 → 2.18.0
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 +22 -20
- package/.next/cache/.previewinfo +1 -1
- package/.next/cache/.rscinfo +1 -1
- package/.next/cache/.tsbuildinfo +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/client-production/index.pack.old +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/.next/diagnostics/framework.json +1 -1
- package/.next/dynamic-css-manifest.json +8 -1
- package/.next/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +4 -4
- package/.next/react-loadable-manifest.json +176 -1
- package/.next/required-server-files.js +3 -2
- package/.next/required-server-files.json +3 -2
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/30.js +1 -1
- package/.next/server/chunks/309.js +1 -0
- package/.next/server/chunks/316.js +1 -0
- package/.next/server/chunks/344.js +1 -0
- package/.next/server/chunks/371.js +1 -0
- package/.next/server/chunks/392.js +1 -1
- package/.next/server/chunks/465.js +1 -0
- package/.next/server/chunks/546.js +1 -0
- package/.next/server/chunks/623.js +1 -0
- package/.next/server/chunks/624.js +1 -0
- package/.next/server/chunks/641.js +1 -0
- package/.next/server/chunks/671.js +1 -1
- package/.next/server/chunks/692.js +1 -0
- package/.next/server/chunks/705.js +1 -0
- package/.next/server/chunks/712.js +1 -1
- package/.next/server/chunks/846.js +1 -0
- package/.next/server/chunks/853.js +15 -0
- package/.next/server/chunks/886.js +1 -0
- package/.next/server/chunks/916.js +1 -0
- package/.next/server/chunks/953.js +1 -0
- package/.next/server/chunks/961.js +1 -0
- package/.next/server/chunks/968.js +1 -0
- package/.next/server/dynamic-css-manifest.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.html +28 -1
- package/.next/server/pages/500.html +28 -1
- package/.next/server/pages/_app.js +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js +28 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js +28 -1
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/pages/api/dictionary/[locale]/[word].js +1 -1
- package/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
- package/.next/server/pages/api/dictionary/[locale].js +1 -1
- package/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
- package/.next/server/pages/api/solve.js +1 -1
- package/.next/server/pages/api/solve.js.nft.json +1 -1
- package/.next/server/pages/api/verify.js +1 -1
- package/.next/server/pages/api/verify.js.nft.json +1 -1
- package/.next/server/pages/api/visit.js.nft.json +1 -1
- package/.next/server/pages/index.html +28 -1
- package/.next/server/pages/index.js +30 -1
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/index.json +1 -1
- package/.next/server/pages/not-found.html +28 -1
- package/.next/server/pages/not-found.js.nft.json +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/server/webpack-api-runtime.js +1 -1
- package/.next/server/webpack-runtime.js +1 -1
- package/.next/static/FL82obwzFHRzvV6z76I-U/_buildManifest.js +1 -0
- package/.next/static/chunks/101-829ab8a8d310e7a0.js +3 -0
- package/.next/static/chunks/106.e414e88694add27f.js +1 -0
- package/.next/static/chunks/127.125d896a19061d71.js +1 -0
- package/.next/static/chunks/18.8b91e137d239e15c.js +1 -0
- package/.next/static/chunks/277.6785dfaf22fdb0b7.js +1 -0
- package/.next/static/chunks/307.67f52f13e3d60d4e.js +1 -0
- package/.next/static/chunks/341.79535ba85bf1986f.js +1 -0
- package/.next/static/chunks/363.01eed3233f92b6a4.js +1 -0
- package/.next/static/chunks/422.1559ae6756912ca5.js +1 -0
- package/.next/static/chunks/541.dcd9e8b804f88da5.js +1 -0
- package/.next/static/chunks/583.7a46807be14c377e.js +1 -0
- package/.next/static/chunks/631.98d42abad0a60af6.js +1 -0
- package/.next/static/chunks/663.d2c9ca36b26695b8.js +1 -0
- package/.next/static/chunks/711.ba7b8f900dfd40d0.js +1 -0
- package/.next/static/chunks/744.b06c9a3de4a1d877.js +1 -0
- package/.next/static/chunks/820.97b82f751ca49579.js +1 -0
- package/.next/static/chunks/865.a9b563a45848a83c.js +1 -0
- package/.next/static/chunks/912.ff8037ba9d4db5c8.js +1 -0
- package/.next/static/chunks/939.19b33a3d3c351d73.js +1 -0
- package/.next/static/chunks/990.61296e5870b91f11.js +1 -0
- package/.next/static/chunks/framework-626cbd48ac5aca57.js +1 -0
- package/.next/static/chunks/main-b92e08f3fc96dd8d.js +5 -0
- package/.next/static/chunks/pages/_app-ba5d628e81a15461.js +1 -0
- package/.next/static/chunks/pages/{_error-afeda7c5231b6c3c.js → _error-f0290a98eb3ed0ec.js} +1 -1
- package/.next/static/chunks/pages/index-5f9fa6ac3cd3d97b.js +1 -0
- package/.next/static/chunks/pages/not-found-23d61fd3ed791cad.js +1 -0
- package/.next/static/chunks/webpack-e34c3ae12275e978.js +1 -0
- package/.next/static/css/2d03f0da2c678dfc.css +1 -0
- package/.next/static/css/7b6724d2df70f48f.css +1 -0
- package/.next/static/css/abc2425d3ba607bc.css +1 -0
- package/.next/static/css/b736be3bd02b5d99.css +1 -0
- package/.next/static/css/b74cd7de82dabcdd.css +1 -0
- package/.next/static/css/c403ce739a9c0d83.css +1 -0
- package/.next/static/css/ca311e6c030663d4.css +1 -0
- package/.next/static/css/dee878eb64099d92.css +1 -0
- package/.next/static/css/fbfdce70731d0d2b.css +1 -0
- package/.next/trace +21 -21
- package/.next/trace-build +1 -1
- package/empty-module.js +2 -0
- package/next.config.js +13 -8
- package/package.json +35 -16
- package/public/llms.txt +11 -0
- package/public/robots.txt +4 -0
- package/scripts/generate-scss-types.ts +112 -0
- package/src/@types/scss.d.ts +6 -9
- package/src/@types/svg.d.ts +1 -1
- package/src/components/Alert/Alert.module.scss.d.ts +13 -0
- package/src/components/Alert/Alert.tsx +4 -1
- package/src/components/Badge/Badge.module.scss.d.ts +6 -0
- package/src/components/Board/Board.module.scss +10 -0
- package/src/components/Board/Board.module.scss.d.ts +17 -0
- package/src/components/Board/Board.tsx +14 -26
- package/src/components/Board/BoardPure.tsx +54 -49
- package/src/components/Board/components/Actions/Actions.module.scss +18 -18
- package/src/components/Board/components/Actions/Actions.module.scss.d.ts +7 -0
- package/src/components/Board/components/Actions/Actions.tsx +6 -3
- package/src/components/Board/components/Actions/lib.ts +3 -1
- package/src/components/Board/components/Cell/Cell.module.scss.d.ts +13 -0
- package/src/components/Board/components/Cell/Cell.tsx +32 -34
- package/src/components/Board/components/InputPrompt/InputPrompt.module.scss.d.ts +10 -0
- package/src/components/Board/components/InputPrompt/InputPrompt.tsx +1 -1
- package/src/components/Board/components/ToggleDirectionButton/ToggleDirectionButton.module.scss.d.ts +8 -0
- package/src/components/Board/components/ToggleDirectionButton/ToggleDirectionButton.tsx +2 -2
- package/src/components/Board/getBoardBackground.ts +175 -0
- package/src/components/Board/hooks/index.ts +0 -1
- package/src/components/Board/hooks/useBoardStyle.ts +10 -20
- package/src/components/Board/hooks/useFloatingActions.ts +3 -6
- package/src/components/Board/hooks/useGrid.ts +23 -9
- package/src/components/Board/selectors.ts +1 -1
- package/src/components/Button/Button.module.scss.d.ts +12 -0
- package/src/components/Dictionary/Dictionary.module.scss +8 -22
- package/src/components/Dictionary/Dictionary.module.scss.d.ts +14 -0
- package/src/components/Dictionary/Dictionary.tsx +1 -10
- package/src/components/DictionaryInput/DictionaryInput.module.scss.d.ts +7 -0
- package/src/components/DictionaryInput/DictionaryInput.tsx +1 -1
- package/src/components/EmptyState/EmptyState.module.scss.d.ts +7 -0
- package/src/components/EmptyState/EmptyState.tsx +1 -1
- package/src/components/IconButton/IconButton.module.scss.d.ts +8 -0
- package/src/components/Key/Key.module.scss.d.ts +6 -0
- package/src/components/Keys/Arrows/Arrows.module.scss.d.ts +11 -0
- package/src/components/Keys/Arrows/Arrows.tsx +4 -1
- package/src/components/Keys/index.tsx +1 -1
- package/src/components/Loading/Loading.module.scss.d.ts +9 -0
- package/src/components/Loading/Loading.tsx +1 -1
- package/src/components/Logo/Logo.tsx +4 -9
- package/src/components/Logo/LogoBlueprint.tsx +1 -0
- package/src/components/Modal/Modal.module.scss.d.ts +15 -0
- package/src/components/Modal/Modal.tsx +16 -3
- package/src/components/Modal/components/Section/Section.module.scss.d.ts +7 -0
- package/src/components/NavButtons/NavButtons.module.scss +20 -0
- package/src/components/NavButtons/NavButtons.module.scss.d.ts +13 -0
- package/src/components/NavButtons/NavButtons.tsx +29 -45
- package/src/components/NotFound/NotFound.module.scss.d.ts +9 -0
- package/src/components/NotFound/NotFound.tsx +1 -1
- package/src/components/PlainTiles/PlainTiles.module.scss.d.ts +11 -0
- package/src/components/PlainTiles/PlainTiles.tsx +0 -1
- package/src/components/PlainTiles/Tile.tsx +3 -4
- package/src/components/PlainTiles/lib.ts +4 -19
- package/src/components/PlainTiles/types.ts +0 -1
- package/src/components/Progress/Progress.module.scss +7 -0
- package/src/components/Progress/Progress.module.scss.d.ts +6 -0
- package/src/components/Progress/Progress.tsx +2 -11
- package/src/components/Rack/Rack.module.scss +3 -0
- package/src/components/Rack/Rack.module.scss.d.ts +10 -0
- package/src/components/Rack/Rack.tsx +8 -11
- package/src/components/Rack/components/InputPrompt/InputPrompt.module.scss +2 -0
- package/src/components/Rack/components/InputPrompt/InputPrompt.module.scss.d.ts +7 -0
- package/src/components/Rack/components/InputPrompt/InputPrompt.tsx +1 -13
- package/src/components/Rack/components/InputPrompt/lib.ts +1 -1
- package/src/components/Rack/components/RackTile/RackTile.module.scss.d.ts +6 -0
- package/src/components/Rack/components/RackTile/RackTile.tsx +5 -4
- package/src/components/Rack/selectors.ts +1 -1
- package/src/components/Radio/Radio.module.scss.d.ts +12 -0
- package/src/components/Results/Cell.tsx +3 -12
- package/src/components/Results/Header.tsx +9 -18
- package/src/components/Results/HeaderButton.tsx +4 -5
- package/src/components/Results/Result.tsx +4 -15
- package/src/components/Results/Results.module.scss +4 -7
- package/src/components/Results/Results.module.scss.d.ts +27 -0
- package/src/components/Results/Results.tsx +14 -5
- package/src/components/Results/SolveButton.tsx +1 -1
- package/src/components/Results/types.ts +3 -3
- package/src/components/ResultsInput/ResultsInput.module.scss.d.ts +7 -0
- package/src/components/ResultsInput/ResultsInput.tsx +1 -1
- package/src/components/Solver/Solver.module.scss +6 -5
- package/src/components/Solver/Solver.module.scss.d.ts +20 -0
- package/src/components/Solver/Solver.tsx +23 -24
- package/src/components/Solver/components/InsertButton/InsertButton.module.scss.d.ts +7 -0
- package/src/components/Solver/components/InsertButton/InsertButton.tsx +1 -1
- package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.module.scss.d.ts +18 -0
- package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +3 -1
- package/src/components/Spinner/Spinner.module.scss.d.ts +10 -0
- package/src/components/Tile/Tile.module.scss +3 -0
- package/src/components/Tile/Tile.module.scss.d.ts +19 -0
- package/src/components/Tile/Tile.tsx +5 -14
- package/src/components/Tile/TilePure.tsx +2 -12
- package/src/components/Tooltip/Tooltip.module.scss.d.ts +7 -0
- package/src/components/Tooltip/Tooltip.tsx +14 -3
- package/src/components/Tooltip/useTooltip.ts +2 -1
- package/src/hooks/useColumns.ts +4 -7
- package/src/hooks/useDeferredRender.ts +20 -0
- package/src/hooks/useDirection.ts +4 -3
- package/src/hooks/useLanguage.ts +2 -2
- package/src/hooks/useLocalStorage.ts +32 -8
- package/src/hooks/useMedia.ts +26 -26
- package/src/i18n/constants.ts +2 -15
- package/src/i18n/i18n.ts +18 -17
- package/src/i18n/languages/english.json +0 -1
- package/src/i18n/languages/french.json +0 -1
- package/src/i18n/languages/german.json +0 -1
- package/src/i18n/languages/persian.json +0 -1
- package/src/i18n/languages/polish.json +0 -1
- package/src/i18n/languages/romanian.json +0 -1
- package/src/i18n/languages/spanish.json +0 -1
- package/src/i18n/languages/turkish.json +0 -1
- package/src/i18n/localeIcons.ts +24 -0
- package/src/lib/localeTransliterate.test.ts +5 -0
- package/src/lib/localeTransliterate.ts +26 -6
- package/src/lib/waitForIdleOrFirstIntent.ts +33 -0
- package/src/modals/DictionaryModal/DictionaryModal.module.scss.d.ts +8 -0
- package/src/modals/DictionaryModal/DictionaryModal.tsx +3 -1
- package/src/modals/KeyMapModal/KeyMapModal.tsx +3 -1
- package/src/modals/KeyMapModal/components/Mapping/Mapping.module.scss.d.ts +11 -0
- package/src/modals/MenuModal/MenuModal.module.scss +5 -0
- package/src/modals/MenuModal/MenuModal.module.scss.d.ts +10 -0
- package/src/modals/MenuModal/MenuModal.tsx +16 -5
- package/src/modals/RemainingTilesModal/RemainingTilesModal.module.scss +4 -1
- package/src/modals/RemainingTilesModal/RemainingTilesModal.module.scss.d.ts +9 -0
- package/src/modals/RemainingTilesModal/RemainingTilesModal.tsx +4 -6
- package/src/modals/RemainingTilesModal/components/Character/Character.module.scss +1 -0
- package/src/modals/RemainingTilesModal/components/Character/Character.module.scss.d.ts +12 -0
- package/src/modals/RemainingTilesModal/components/Character/Character.tsx +5 -12
- package/src/modals/ResultsModal/ResultsModal.module.scss.d.ts +8 -0
- package/src/modals/ResultsModal/ResultsModal.tsx +8 -4
- package/src/modals/SettingsModal/SettingsModal.tsx +2 -2
- package/src/modals/SettingsModal/components/AutoGroupTilesSetting/AutoGroupTilesSetting.module.scss.d.ts +7 -0
- package/src/modals/SettingsModal/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +1 -1
- package/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.module.scss.d.ts +7 -0
- package/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.tsx +1 -1
- package/src/modals/SettingsModal/components/HighlightUnreachableCellsSetting/HighlightUnreachableCellsSetting.module.scss.d.ts +7 -0
- package/src/modals/SettingsModal/components/HighlightUnreachableCellsSetting/HighlightUnreachableCellsSetting.tsx +1 -1
- package/src/modals/SettingsModal/components/InputModeSetting/InputModeSetting.module.scss.d.ts +7 -0
- package/src/modals/SettingsModal/components/InputModeSetting/InputModeSetting.tsx +1 -1
- package/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.module.scss.d.ts +8 -0
- package/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.tsx +24 -21
- package/src/modals/SettingsModal/components/RemoveCellFiltersSetting/RemoveCellFiltersSetting.module.scss.d.ts +7 -0
- package/src/modals/SettingsModal/components/RemoveCellFiltersSetting/RemoveCellFiltersSetting.tsx +1 -1
- package/src/modals/SettingsModal/components/ShowCoordinatesSetting/ShowCoordinatesSetting.module.scss.d.ts +7 -0
- package/src/modals/SettingsModal/components/ShowCoordinatesSetting/ShowCoordinatesSetting.tsx +1 -5
- package/src/modals/WordsModal/WordsModal.module.scss.d.ts +11 -0
- package/src/modals/WordsModal/WordsModal.tsx +4 -2
- package/src/modals/preload.ts +24 -0
- package/src/pages/_app.tsx +5 -8
- package/src/pages/_document.tsx +91 -5
- package/src/pages/api/dictionary/[locale]/[word].ts +2 -2
- package/src/pages/api/dictionary/[locale]/index.ts +80 -3
- package/src/pages/api/solve.ts +3 -3
- package/src/pages/api/verify.ts +12 -3
- package/src/pages/index.module.scss +1 -0
- package/src/pages/index.module.scss.d.ts +11 -0
- package/src/pages/index.tsx +98 -38
- package/src/pages/not-found.tsx +1 -1
- package/src/parameters/index.ts +24 -93
- package/src/sdk/solve.ts +13 -7
- package/src/sdk/verify.ts +12 -6
- package/src/service-worker/appShell.test.ts +86 -0
- package/src/service-worker/appShell.ts +39 -0
- package/src/service-worker/index.ts +4 -5
- package/src/serviceWorkerManager.ts +5 -19
- package/src/solver-worker/client.test.ts +151 -0
- package/src/solver-worker/client.ts +106 -0
- package/src/solver-worker/dictionaries/constants.ts +9 -0
- package/src/solver-worker/dictionaries/getDictionary.ts +21 -0
- package/src/solver-worker/dictionaries/index.ts +2 -0
- package/src/solver-worker/dictionaries/revalidateDictionary.test.ts +199 -0
- package/src/solver-worker/dictionaries/revalidateDictionary.ts +86 -0
- package/src/solver-worker/dictionaries/revalidatedAt.ts +43 -0
- package/src/solver-worker/getGaddag.test.ts +109 -0
- package/src/solver-worker/getGaddag.ts +62 -0
- package/src/solver-worker/index.ts +1 -0
- package/src/solver-worker/index.worker.ts +124 -0
- package/src/solver-worker/messages.ts +20 -0
- package/src/state/actions.ts +1 -1
- package/src/state/app/index.ts +4 -0
- package/src/state/app/initialState.ts +6 -0
- package/src/state/app/selectors.ts +5 -0
- package/src/state/app/slice.ts +20 -0
- package/src/state/app/types.ts +4 -0
- package/src/state/board/initialState.ts +1 -2
- package/src/state/i18n/index.ts +4 -0
- package/src/state/i18n/initialState.ts +5 -0
- package/src/state/i18n/selectors.ts +3 -0
- package/src/state/i18n/slice.ts +16 -0
- package/src/state/i18n/types.ts +7 -0
- package/src/state/index.ts +3 -0
- package/src/state/lib.ts +1 -1
- package/src/state/localStorage.ts +86 -29
- package/src/state/rack/initialState.ts +1 -2
- package/src/state/rack/slice.ts +4 -1
- package/src/state/results/lib.ts +5 -5
- package/src/state/results/selectors.ts +1 -1
- package/src/state/sagas.ts +139 -13
- package/src/state/selectors.ts +1 -1
- package/src/state/settings/initialState.ts +7 -10
- package/src/state/settings/selectors.ts +7 -2
- package/src/state/settings/slice.ts +5 -2
- package/src/state/store.ts +4 -0
- package/src/state/types.ts +4 -0
- package/src/state/useTypedStore.ts +6 -0
- package/src/styles/_tokens.scss +1 -0
- package/src/styles/global.scss +9 -0
- package/src/styles/variables.module.scss +0 -21
- package/src/styles/variables.module.scss.d.ts +27 -0
- package/src/styles/variables.scss +46 -2
- package/src/types/api.ts +1 -2
- package/src/types/index.ts +1 -2
- package/tsconfig.json +4 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/.next/server/chunks/318.js +0 -3
- package/.next/server/chunks/791.js +0 -15
- package/.next/static/chunks/framework-3cf15b8041c59dd3.js +0 -1
- package/.next/static/chunks/main-852475ca502b4e49.js +0 -5
- package/.next/static/chunks/pages/_app-a5bbe02710f13d05.js +0 -7
- package/.next/static/chunks/pages/index-ec0f6aeeaf7be227.js +0 -1
- package/.next/static/chunks/pages/not-found-9e076427bad69d90.js +0 -1
- package/.next/static/chunks/webpack-1a7a166b34ed8d24.js +0 -1
- package/.next/static/css/0af35adb4bab56f0.css +0 -2
- package/.next/static/css/a78e04fe95452380.css +0 -1
- package/.next/static/vYpMmuC_yEurZGcyGVnLf/_buildManifest.js +0 -1
- package/src/app-layout/AppLayoutContext.tsx +0 -25
- package/src/app-layout/index.ts +0 -1
- package/src/app-layout/useAppLayoutValue.ts +0 -112
- package/src/components/Board/hooks/useBackgroundImage.tsx +0 -279
- package/src/components/index.ts +0 -26
- package/src/hooks/index.ts +0 -12
- package/src/hooks/useOnWindowResize.ts +0 -11
- package/src/hooks/useViewportSize.ts +0 -17
- package/src/i18n/index.ts +0 -2
- package/src/icons/Flag.svg +0 -4
- package/src/icons/Star.svg +0 -4
- package/src/icons/index.ts +0 -49
- package/src/lib/getTileSizes.ts +0 -13
- package/src/lib/index.ts +0 -24
- package/src/modals/index.ts +0 -7
- package/src/sdk/getDictionary.ts +0 -9
- package/src/service-worker/average.ts +0 -7
- package/src/service-worker/dictionaries/constants.ts +0 -5
- package/src/service-worker/dictionaries/getDictionary.ts +0 -20
- package/src/service-worker/dictionaries/index.ts +0 -2
- package/src/service-worker/dictionaries/revalidateDictionary.ts +0 -33
- package/src/service-worker/getTrie.ts +0 -24
- package/src/service-worker/routeSolveRequests.ts +0 -91
- package/src/service-worker/routeVerifyRequests.ts +0 -37
- /package/.next/static/{vYpMmuC_yEurZGcyGVnLf → FL82obwzFHRzvV6z76I-U}/_ssgManifest.js +0 -0
- /package/src/{service-worker → solver-worker}/dictionaries/expirationManager.ts +0 -0
- /package/src/{service-worker → solver-worker}/dictionaries/getDictionaryUrl.ts +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Generated by scripts/generate-scss-types.ts - do not edit.
|
|
2
|
+
declare const styles: {
|
|
3
|
+
readonly cell: string;
|
|
4
|
+
readonly content: string;
|
|
5
|
+
readonly coordinates: string;
|
|
6
|
+
readonly emptyState: string;
|
|
7
|
+
readonly header: string;
|
|
8
|
+
readonly headerButton: string;
|
|
9
|
+
readonly headerButtonIcon: string;
|
|
10
|
+
readonly headerButtonLabel: string;
|
|
11
|
+
readonly highlight: string;
|
|
12
|
+
readonly highlighted: string;
|
|
13
|
+
readonly input: string;
|
|
14
|
+
readonly list: string;
|
|
15
|
+
readonly listContainer: string;
|
|
16
|
+
readonly outdated: string;
|
|
17
|
+
readonly points: string;
|
|
18
|
+
readonly result: string;
|
|
19
|
+
readonly resultContent: string;
|
|
20
|
+
readonly results: string;
|
|
21
|
+
readonly solveButton: string;
|
|
22
|
+
readonly sortIcon: string;
|
|
23
|
+
readonly stat: string;
|
|
24
|
+
readonly word: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default styles;
|
|
@@ -3,9 +3,9 @@ import { useEffect, useMemo, type FunctionComponent } from 'react';
|
|
|
3
3
|
import { List, useListRef } from 'react-window';
|
|
4
4
|
import { useDebounce } from 'use-debounce';
|
|
5
5
|
|
|
6
|
-
import { useLatest } from '@/hooks';
|
|
7
|
-
import { LOCALE_FEATURES } from '@/i18n';
|
|
8
|
-
import { RESULTS_ITEM_HEIGHT } from '@/parameters';
|
|
6
|
+
import { useLatest } from '@/hooks/useLatest';
|
|
7
|
+
import { LOCALE_FEATURES } from '@/i18n/constants';
|
|
8
|
+
import { RESULTS_ITEM_HEIGHT, RESULTS_OVERSCAN_COUNT } from '@/parameters';
|
|
9
9
|
import {
|
|
10
10
|
selectAreResultsOutdated,
|
|
11
11
|
selectLocale,
|
|
@@ -44,7 +44,14 @@ export const Results: FunctionComponent<Props> = ({ callbacks, className, highli
|
|
|
44
44
|
const isOutdated = useTypedSelector(selectAreResultsOutdated);
|
|
45
45
|
const error = useTypedSelector(selectSolveError);
|
|
46
46
|
const itemData = useMemo<ResultData>(
|
|
47
|
-
() => ({
|
|
47
|
+
() => ({
|
|
48
|
+
highlightedIndex,
|
|
49
|
+
results,
|
|
50
|
+
onBlur: callbacks.onBlur,
|
|
51
|
+
onClick: callbacks.onClick,
|
|
52
|
+
onFocus: callbacks.onFocus,
|
|
53
|
+
onMouseEnter: callbacks.onMouseEnter,
|
|
54
|
+
}),
|
|
48
55
|
[callbacks, highlightedIndex, results],
|
|
49
56
|
);
|
|
50
57
|
const listRef = useListRef(null);
|
|
@@ -74,6 +81,7 @@ export const Results: FunctionComponent<Props> = ({ callbacks, className, highli
|
|
|
74
81
|
aria-busy={isLoadingDebounced}
|
|
75
82
|
aria-label={translate('results')}
|
|
76
83
|
className={classNames(styles.results, className)}
|
|
84
|
+
data-outdated={isOutdated}
|
|
77
85
|
data-testid="results"
|
|
78
86
|
role="region"
|
|
79
87
|
>
|
|
@@ -111,13 +119,14 @@ export const Results: FunctionComponent<Props> = ({ callbacks, className, highli
|
|
|
111
119
|
)}
|
|
112
120
|
|
|
113
121
|
{!isOutdated && results.length > 0 && (
|
|
114
|
-
<div className={styles.listContainer}>
|
|
122
|
+
<div className={styles.listContainer} onMouseLeave={callbacks.onMouseLeave}>
|
|
115
123
|
<List
|
|
116
124
|
className={classNames(styles.list, {
|
|
117
125
|
[styles.outdated]: isOutdated,
|
|
118
126
|
})}
|
|
119
127
|
dir={direction}
|
|
120
128
|
listRef={listRef}
|
|
129
|
+
overscanCount={RESULTS_OVERSCAN_COUNT}
|
|
121
130
|
rowComponent={Result}
|
|
122
131
|
rowCount={results.length}
|
|
123
132
|
rowHeight={RESULTS_ITEM_HEIGHT}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { type Result } from '@scrabble-solver/types';
|
|
2
|
-
import { type FocusEvent, type MouseEvent } from 'react';
|
|
2
|
+
import { type FocusEvent, type MouseEvent, type MouseEventHandler } from 'react';
|
|
3
3
|
|
|
4
4
|
export interface ResultCallbacks {
|
|
5
5
|
onBlur?: (result: Result, event: FocusEvent) => void;
|
|
6
6
|
onClick?: (result: Result, event: MouseEvent) => void;
|
|
7
7
|
onFocus?: (result: Result, event: FocusEvent) => void;
|
|
8
8
|
onMouseEnter?: (result: Result, event: MouseEvent) => void;
|
|
9
|
-
onMouseLeave?:
|
|
9
|
+
onMouseLeave?: MouseEventHandler;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export interface ResultData extends ResultCallbacks {
|
|
12
|
+
export interface ResultData extends Omit<ResultCallbacks, 'onMouseLeave'> {
|
|
13
13
|
highlightedIndex?: number;
|
|
14
14
|
results: Result[] | undefined;
|
|
15
15
|
}
|
|
@@ -2,7 +2,7 @@ import classNames from 'classnames';
|
|
|
2
2
|
import { type ChangeEvent, type FunctionComponent, type SubmitEventHandler, useState } from 'react';
|
|
3
3
|
import { useDispatch } from 'react-redux';
|
|
4
4
|
|
|
5
|
-
import { isRegExp } from '@/lib';
|
|
5
|
+
import { isRegExp } from '@/lib/isRegExp';
|
|
6
6
|
import { resultsSlice, selectResultsQuery, useTranslate, useTypedSelector } from '@/state';
|
|
7
7
|
|
|
8
8
|
import styles from './ResultsInput.module.scss';
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
@use 'styles/mixins' as *;
|
|
2
2
|
|
|
3
3
|
.solver {
|
|
4
|
-
--spacing: var(--spacing
|
|
4
|
+
--spacing: var(--components-spacing);
|
|
5
5
|
|
|
6
6
|
position: relative;
|
|
7
7
|
margin: 0 var(--spacing);
|
|
8
8
|
display: flex;
|
|
9
9
|
flex-direction: column;
|
|
10
10
|
|
|
11
|
-
@include media('<xl') {
|
|
12
|
-
--spacing: var(--spacing--l);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
@include media('<l', 'touch') {
|
|
16
12
|
margin-bottom: calc(3 * var(--spacing--l) + var(--button--icon--size));
|
|
17
13
|
}
|
|
@@ -108,6 +104,11 @@
|
|
|
108
104
|
|
|
109
105
|
.controls {
|
|
110
106
|
width: 100%;
|
|
107
|
+
max-width: var(--controls-max-width);
|
|
108
|
+
|
|
109
|
+
@include media('>=l') {
|
|
110
|
+
display: none;
|
|
111
|
+
}
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
.emptyState {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Generated by scripts/generate-scss-types.ts - do not edit.
|
|
2
|
+
declare const styles: {
|
|
3
|
+
readonly board: string;
|
|
4
|
+
readonly boardContainer: string;
|
|
5
|
+
readonly bottomContainer: string;
|
|
6
|
+
readonly bottomContent: string;
|
|
7
|
+
readonly column: string;
|
|
8
|
+
readonly container: string;
|
|
9
|
+
readonly content: string;
|
|
10
|
+
readonly controls: string;
|
|
11
|
+
readonly dictionary: string;
|
|
12
|
+
readonly dictionaryContainer: string;
|
|
13
|
+
readonly dictionaryInput: string;
|
|
14
|
+
readonly emptyState: string;
|
|
15
|
+
readonly results: string;
|
|
16
|
+
readonly solver: string;
|
|
17
|
+
readonly submitInput: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default styles;
|
|
@@ -3,8 +3,8 @@ import classNames from 'classnames';
|
|
|
3
3
|
import { type FunctionComponent, memo, type SyntheticEvent, useEffect, useMemo } from 'react';
|
|
4
4
|
import { useDispatch } from 'react-redux';
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { useIsTouchDevice } from '@/hooks/useIsTouchDevice';
|
|
7
|
+
import { useMediaQuery } from '@/hooks/useMediaQuery';
|
|
8
8
|
import {
|
|
9
9
|
resultsSlice,
|
|
10
10
|
selectAreResultsOutdated,
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
solveSlice,
|
|
15
15
|
useTranslate,
|
|
16
16
|
useTypedSelector,
|
|
17
|
+
useTypedStore,
|
|
17
18
|
} from '@/state';
|
|
18
19
|
|
|
19
20
|
import { Alert } from '../Alert';
|
|
@@ -35,16 +36,16 @@ const SolverBase: FunctionComponent<Props> = ({ className, onShowResults }) => {
|
|
|
35
36
|
const dispatch = useDispatch();
|
|
36
37
|
const translate = useTranslate();
|
|
37
38
|
const isTouchDevice = useIsTouchDevice();
|
|
38
|
-
const
|
|
39
|
+
const showCompactControls = useMediaQuery('<l');
|
|
39
40
|
const error = useTypedSelector(selectSolveError);
|
|
40
41
|
const isOutdated = useTypedSelector(selectAreResultsOutdated);
|
|
41
|
-
const resultCandidate = useTypedSelector(selectResultCandidate);
|
|
42
42
|
const results = useTypedSelector(selectProcessedResults);
|
|
43
|
+
const store = useTypedStore();
|
|
43
44
|
const [bestResult] = results || [];
|
|
44
45
|
const touchCallbacks = useMemo(
|
|
45
46
|
() => ({
|
|
46
47
|
onClick: (result: Result) => {
|
|
47
|
-
const isSelected = result ===
|
|
48
|
+
const isSelected = result === selectResultCandidate(store.getState());
|
|
48
49
|
|
|
49
50
|
if (isSelected) {
|
|
50
51
|
dispatch(resultsSlice.actions.applyResult(result));
|
|
@@ -53,7 +54,7 @@ const SolverBase: FunctionComponent<Props> = ({ className, onShowResults }) => {
|
|
|
53
54
|
}
|
|
54
55
|
},
|
|
55
56
|
}),
|
|
56
|
-
[dispatch,
|
|
57
|
+
[dispatch, store],
|
|
57
58
|
);
|
|
58
59
|
const mouseCallbacks = useMemo(
|
|
59
60
|
() => ({
|
|
@@ -112,27 +113,25 @@ const SolverBase: FunctionComponent<Props> = ({ className, onShowResults }) => {
|
|
|
112
113
|
<div className={styles.bottomContainer}>
|
|
113
114
|
<div className={styles.bottomContent}>
|
|
114
115
|
<form onSubmit={handleSubmit}>
|
|
115
|
-
<Rack
|
|
116
|
+
<Rack />
|
|
116
117
|
<input className={styles.submitInput} tabIndex={-1} type="submit" />
|
|
117
118
|
</form>
|
|
118
119
|
|
|
119
|
-
{
|
|
120
|
-
<
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
{error
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
{
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
</div>
|
|
135
|
-
)}
|
|
120
|
+
<div className={styles.controls}>
|
|
121
|
+
<ResultCandidatePicker onResultClick={onShowResults} />
|
|
122
|
+
|
|
123
|
+
{error && (
|
|
124
|
+
<Alert className={styles.emptyState} variant="error">
|
|
125
|
+
{error.message}
|
|
126
|
+
</Alert>
|
|
127
|
+
)}
|
|
128
|
+
|
|
129
|
+
{results && results.length === 0 && !isOutdated && (
|
|
130
|
+
<Alert className={styles.emptyState} variant="warning">
|
|
131
|
+
{translate('results.empty-state.no-results')}
|
|
132
|
+
</Alert>
|
|
133
|
+
)}
|
|
134
|
+
</div>
|
|
136
135
|
</div>
|
|
137
136
|
</div>
|
|
138
137
|
</div>
|
|
@@ -2,7 +2,7 @@ import classNames from 'classnames';
|
|
|
2
2
|
import { type FunctionComponent } from 'react';
|
|
3
3
|
import { useDispatch } from 'react-redux';
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import Check from '@/icons/Check.svg';
|
|
6
6
|
import { resultsSlice, selectAreResultsOutdated, selectResultCandidate, useTranslate, useTypedSelector } from '@/state';
|
|
7
7
|
|
|
8
8
|
import { Button } from '../../../Button';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Generated by scripts/generate-scss-types.ts - do not edit.
|
|
2
|
+
declare const styles: {
|
|
3
|
+
readonly bothEnabled: string;
|
|
4
|
+
readonly button: string;
|
|
5
|
+
readonly buttons: string;
|
|
6
|
+
readonly content: string;
|
|
7
|
+
readonly icon: string;
|
|
8
|
+
readonly iconContainer: string;
|
|
9
|
+
readonly insert: string;
|
|
10
|
+
readonly loading: string;
|
|
11
|
+
readonly points: string;
|
|
12
|
+
readonly resultCandidate: string;
|
|
13
|
+
readonly resultCandidatePicker: string;
|
|
14
|
+
readonly spinnerContainer: string;
|
|
15
|
+
readonly word: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default styles;
|
|
@@ -2,7 +2,9 @@ import classNames from 'classnames';
|
|
|
2
2
|
import { type FunctionComponent, type HTMLProps, type MouseEventHandler } from 'react';
|
|
3
3
|
import { useDispatch } from 'react-redux';
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import ChevronDown from '@/icons/ChevronDown.svg';
|
|
6
|
+
import ChevronLeft from '@/icons/ChevronLeft.svg';
|
|
7
|
+
import ChevronRight from '@/icons/ChevronRight.svg';
|
|
6
8
|
import {
|
|
7
9
|
resultsSlice,
|
|
8
10
|
selectAreResultsOutdated,
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
--background-color: transparent;
|
|
5
5
|
|
|
6
6
|
position: relative;
|
|
7
|
+
width: var(--tile-size, auto);
|
|
8
|
+
height: var(--tile-size, auto);
|
|
7
9
|
display: flex;
|
|
8
10
|
align-items: center;
|
|
9
11
|
justify-content: center;
|
|
@@ -92,6 +94,7 @@
|
|
|
92
94
|
.points {
|
|
93
95
|
@include text-stroke(var(--background-color), 1px);
|
|
94
96
|
|
|
97
|
+
font-size: max(10px, calc(var(--tile-size) * 0.25));
|
|
95
98
|
position: absolute;
|
|
96
99
|
inset-block-end: 1%;
|
|
97
100
|
inset-inline-end: 9%;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Generated by scripts/generate-scss-types.ts - do not edit.
|
|
2
|
+
declare const styles: {
|
|
3
|
+
readonly alert: string;
|
|
4
|
+
readonly blank: string;
|
|
5
|
+
readonly empty: string;
|
|
6
|
+
readonly highlighted: string;
|
|
7
|
+
readonly input: string;
|
|
8
|
+
readonly invalid: string;
|
|
9
|
+
readonly points: string;
|
|
10
|
+
readonly points1: string;
|
|
11
|
+
readonly points2: string;
|
|
12
|
+
readonly points3: string;
|
|
13
|
+
readonly points4: string;
|
|
14
|
+
readonly points5: string;
|
|
15
|
+
readonly raised: string;
|
|
16
|
+
readonly tile: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default styles;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMergeRefs } from '@floating-ui/react';
|
|
2
2
|
import { EMPTY_CELL } from '@scrabble-solver/constants';
|
|
3
|
+
import { type Locale } from '@scrabble-solver/types';
|
|
3
4
|
import {
|
|
4
5
|
type ChangeEventHandler,
|
|
5
6
|
type FocusEventHandler,
|
|
@@ -9,13 +10,10 @@ import {
|
|
|
9
10
|
type Ref,
|
|
10
11
|
type TouchEventHandler,
|
|
11
12
|
useCallback,
|
|
12
|
-
useMemo,
|
|
13
13
|
useRef,
|
|
14
14
|
} from 'react';
|
|
15
15
|
|
|
16
|
-
import {
|
|
17
|
-
import { getTileSizes, noop } from '@/lib';
|
|
18
|
-
import { selectLocale, useTypedSelector } from '@/state';
|
|
16
|
+
import { noop } from '@/lib/noop';
|
|
19
17
|
|
|
20
18
|
import { TilePure } from './TilePure';
|
|
21
19
|
|
|
@@ -29,10 +27,10 @@ interface Props {
|
|
|
29
27
|
inputRef?: Ref<HTMLInputElement | null>;
|
|
30
28
|
isBlank?: boolean;
|
|
31
29
|
isValid?: boolean;
|
|
30
|
+
locale: Locale;
|
|
32
31
|
placeholder?: string;
|
|
33
32
|
points?: number;
|
|
34
33
|
raised?: boolean;
|
|
35
|
-
size: number;
|
|
36
34
|
tabIndex?: number;
|
|
37
35
|
onChange?: ChangeEventHandler<HTMLInputElement>;
|
|
38
36
|
onFocus?: FocusEventHandler<HTMLInputElement>;
|
|
@@ -51,10 +49,10 @@ export const Tile: FunctionComponent<Props> = ({
|
|
|
51
49
|
inputRef,
|
|
52
50
|
isBlank,
|
|
53
51
|
isValid,
|
|
52
|
+
locale,
|
|
54
53
|
placeholder,
|
|
55
54
|
points,
|
|
56
55
|
raised,
|
|
57
|
-
size,
|
|
58
56
|
tabIndex,
|
|
59
57
|
onChange,
|
|
60
58
|
onFocus = noop,
|
|
@@ -62,15 +60,10 @@ export const Tile: FunctionComponent<Props> = ({
|
|
|
62
60
|
onMouseDown = noop,
|
|
63
61
|
onTouchStart = noop,
|
|
64
62
|
}) => {
|
|
65
|
-
const locale = useTypedSelector(selectLocale);
|
|
66
|
-
const { showTilePoints } = useAppLayout();
|
|
67
|
-
const { pointsFontSize, tileSize } = getTileSizes(size);
|
|
68
|
-
const style = useMemo(() => ({ height: tileSize, width: tileSize }), [tileSize]);
|
|
69
|
-
const pointsStyle = useMemo(() => ({ fontSize: pointsFontSize }), [pointsFontSize]);
|
|
70
63
|
const ref = useRef<HTMLInputElement>(null);
|
|
71
64
|
const mergedRef = useMergeRefs(inputRef ? [ref, inputRef] : [ref]);
|
|
72
65
|
const isEmpty = !character || character === EMPTY_CELL;
|
|
73
|
-
const canShowPoints =
|
|
66
|
+
const canShowPoints = (!isEmpty || isBlank) && typeof points !== 'undefined';
|
|
74
67
|
const pointsFormatted = typeof points === 'number' ? points.toLocaleString(locale) : '';
|
|
75
68
|
|
|
76
69
|
const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback(
|
|
@@ -96,9 +89,7 @@ export const Tile: FunctionComponent<Props> = ({
|
|
|
96
89
|
placeholder={placeholder}
|
|
97
90
|
points={points}
|
|
98
91
|
pointsFormatted={pointsFormatted}
|
|
99
|
-
pointsStyle={pointsStyle}
|
|
100
92
|
raised={raised}
|
|
101
|
-
style={style}
|
|
102
93
|
tabIndex={tabIndex}
|
|
103
94
|
onChange={onChange}
|
|
104
95
|
onFocus={onFocus}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import classNames from 'classnames';
|
|
2
2
|
import {
|
|
3
3
|
type ChangeEventHandler,
|
|
4
|
-
type CSSProperties,
|
|
5
4
|
type FocusEventHandler,
|
|
6
5
|
type FunctionComponent,
|
|
7
6
|
type KeyboardEventHandler,
|
|
@@ -11,7 +10,7 @@ import {
|
|
|
11
10
|
type TouchEventHandler,
|
|
12
11
|
} from 'react';
|
|
13
12
|
|
|
14
|
-
import
|
|
13
|
+
import ExclamationSquareFill from '@/icons/ExclamationSquareFill.svg';
|
|
15
14
|
|
|
16
15
|
import styles from './Tile.module.scss';
|
|
17
16
|
|
|
@@ -29,9 +28,7 @@ interface Props {
|
|
|
29
28
|
placeholder?: string;
|
|
30
29
|
points?: number;
|
|
31
30
|
pointsFormatted?: string;
|
|
32
|
-
pointsStyle?: CSSProperties;
|
|
33
31
|
raised?: boolean;
|
|
34
|
-
style?: CSSProperties;
|
|
35
32
|
tabIndex?: number;
|
|
36
33
|
onChange?: ChangeEventHandler<HTMLInputElement>;
|
|
37
34
|
onFocus?: FocusEventHandler<HTMLInputElement>;
|
|
@@ -54,9 +51,7 @@ const TilePureBase: FunctionComponent<Props> = ({
|
|
|
54
51
|
placeholder,
|
|
55
52
|
points,
|
|
56
53
|
pointsFormatted,
|
|
57
|
-
pointsStyle,
|
|
58
54
|
raised,
|
|
59
|
-
style,
|
|
60
55
|
tabIndex,
|
|
61
56
|
onChange,
|
|
62
57
|
onFocus,
|
|
@@ -78,7 +73,6 @@ const TilePureBase: FunctionComponent<Props> = ({
|
|
|
78
73
|
[styles.raised]: raised,
|
|
79
74
|
})}
|
|
80
75
|
role={highlighted ? 'mark' : undefined}
|
|
81
|
-
style={style}
|
|
82
76
|
>
|
|
83
77
|
{character || placeholder}
|
|
84
78
|
|
|
@@ -103,11 +97,7 @@ const TilePureBase: FunctionComponent<Props> = ({
|
|
|
103
97
|
/>
|
|
104
98
|
)}
|
|
105
99
|
|
|
106
|
-
{canShowPoints &&
|
|
107
|
-
<span className={styles.points} style={pointsStyle}>
|
|
108
|
-
{pointsFormatted}
|
|
109
|
-
</span>
|
|
110
|
-
)}
|
|
100
|
+
{canShowPoints && <span className={styles.points}>{pointsFormatted}</span>}
|
|
111
101
|
|
|
112
102
|
{!isValid && <ExclamationSquareFill aria-hidden="true" className={styles.alert} role="img" />}
|
|
113
103
|
</div>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Placement } from '@floating-ui/react';
|
|
2
2
|
import { type FunctionComponent, type ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { useDeferredRender } from '@/hooks/useDeferredRender';
|
|
5
|
+
import { useIsTouchDevice } from '@/hooks/useIsTouchDevice';
|
|
5
6
|
|
|
6
7
|
import { TooltipContext } from './context';
|
|
7
8
|
import { TooltipContent } from './TooltipContent';
|
|
@@ -15,13 +16,23 @@ interface Props {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export const Tooltip: FunctionComponent<Props> = ({ children, placement, tooltip }) => {
|
|
18
|
-
const
|
|
19
|
+
const canRenderTooltip = useDeferredRender();
|
|
19
20
|
const isTouchDevice = useIsTouchDevice();
|
|
20
21
|
|
|
21
|
-
if (!tooltip || isTouchDevice) {
|
|
22
|
+
if (!tooltip || !canRenderTooltip || isTouchDevice) {
|
|
22
23
|
return children;
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
return (
|
|
27
|
+
<TooltipBase placement={placement} tooltip={tooltip}>
|
|
28
|
+
{children}
|
|
29
|
+
</TooltipBase>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const TooltipBase: FunctionComponent<Props> = ({ children, placement, tooltip }) => {
|
|
34
|
+
const state = useTooltip({ placement });
|
|
35
|
+
|
|
25
36
|
return (
|
|
26
37
|
<TooltipContext.Provider value={state}>
|
|
27
38
|
<TooltipTrigger>{children}</TooltipTrigger>
|
|
@@ -28,6 +28,7 @@ export const useTooltip = ({ placement = 'top' }: TooltipOptions = {}) => {
|
|
|
28
28
|
const arrowRef = useRef(null);
|
|
29
29
|
const data = useFloating({
|
|
30
30
|
placement,
|
|
31
|
+
strategy: 'fixed',
|
|
31
32
|
open: isOpen,
|
|
32
33
|
onOpenChange: setIsOpen,
|
|
33
34
|
whileElementsMounted: autoUpdate,
|
|
@@ -37,7 +38,7 @@ export const useTooltip = ({ placement = 'top' }: TooltipOptions = {}) => {
|
|
|
37
38
|
const { delay } = useDelayGroup(context);
|
|
38
39
|
const hover = useHover(context, { move: false, delay });
|
|
39
40
|
const focus = useFocus(context);
|
|
40
|
-
const dismiss = useDismiss(context);
|
|
41
|
+
const dismiss = useDismiss(context, { ancestorScroll: true });
|
|
41
42
|
const role = useRole(context, { role: 'tooltip' });
|
|
42
43
|
const interactions = useInteractions([hover, focus, dismiss, role]);
|
|
43
44
|
|
package/src/hooks/useColumns.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createSelector } from '@reduxjs/toolkit';
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
|
|
4
|
-
import { LOCALE_FEATURES } from '@/i18n';
|
|
5
|
-
import { selectLocale,
|
|
4
|
+
import { LOCALE_FEATURES } from '@/i18n/constants';
|
|
5
|
+
import { selectLocale, useTypedSelector } from '@/state';
|
|
6
6
|
import { ResultColumnId } from '@/types';
|
|
7
7
|
|
|
8
8
|
import { useMediaQueries } from './useMediaQueries';
|
|
@@ -15,7 +15,7 @@ const COLUMNS_M = [...COLUMNS_XS];
|
|
|
15
15
|
|
|
16
16
|
const COLUMNS_L = [...COLUMNS_XS];
|
|
17
17
|
|
|
18
|
-
const selectColumns = createSelector([selectLocale
|
|
18
|
+
const selectColumns = createSelector([selectLocale], (locale) => {
|
|
19
19
|
const { consonants, vowels } = LOCALE_FEATURES[locale];
|
|
20
20
|
const columns: ResultColumnId[] = [
|
|
21
21
|
ResultColumnId.Word,
|
|
@@ -23,12 +23,9 @@ const selectColumns = createSelector([selectLocale, selectShowCoordinates], (loc
|
|
|
23
23
|
ResultColumnId.BlanksCount,
|
|
24
24
|
ResultColumnId.WordsCount,
|
|
25
25
|
ResultColumnId.Points,
|
|
26
|
+
ResultColumnId.Coordinates,
|
|
26
27
|
];
|
|
27
28
|
|
|
28
|
-
if (showCoordinates !== 'hidden') {
|
|
29
|
-
columns.push(ResultColumnId.Coordinates);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
29
|
if (vowels) {
|
|
33
30
|
columns.push(ResultColumnId.VowelsCount);
|
|
34
31
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* False during SSR and hydration.
|
|
5
|
+
*/
|
|
6
|
+
export const useDeferredRender = (): boolean => {
|
|
7
|
+
const [canRender, setCanRender] = useState(false);
|
|
8
|
+
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const timeoutId = window.setTimeout(() => {
|
|
11
|
+
return setCanRender(true);
|
|
12
|
+
}, 0);
|
|
13
|
+
|
|
14
|
+
return () => {
|
|
15
|
+
return window.clearTimeout(timeoutId);
|
|
16
|
+
};
|
|
17
|
+
}, []);
|
|
18
|
+
|
|
19
|
+
return canRender;
|
|
20
|
+
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import { type TextDirection } from '@scrabble-solver/types';
|
|
1
2
|
import { useEffect } from 'react';
|
|
2
3
|
|
|
3
|
-
import { noop } from '@/lib';
|
|
4
|
+
import { noop } from '@/lib/noop';
|
|
4
5
|
|
|
5
|
-
export const useDirection = (direction:
|
|
6
|
+
export const useDirection = (direction: TextDirection) => {
|
|
6
7
|
useEffect(() => {
|
|
7
8
|
const html = document.body.parentElement;
|
|
8
9
|
|
|
9
|
-
if (!html) {
|
|
10
|
+
if (!html || html.dir === direction) {
|
|
10
11
|
return noop;
|
|
11
12
|
}
|
|
12
13
|
|
package/src/hooks/useLanguage.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
import { noop } from '@/lib';
|
|
3
|
+
import { noop } from '@/lib/noop';
|
|
4
4
|
|
|
5
5
|
export const useLanguage = (language: string) => {
|
|
6
6
|
useEffect(() => {
|
|
7
7
|
const html = document.body.parentElement;
|
|
8
8
|
|
|
9
|
-
if (!html) {
|
|
9
|
+
if (!html || html.lang === language) {
|
|
10
10
|
return noop;
|
|
11
11
|
}
|
|
12
12
|
|