Skip to content

Commit

Permalink
added tanstank-react-router and close sidebar onSwipeLeft
Browse files Browse the repository at this point in the history
  • Loading branch information
LooLzzz committed Sep 2, 2024
1 parent da81554 commit 89e2139
Show file tree
Hide file tree
Showing 16 changed files with 335 additions and 94 deletions.
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
},
"devDependencies": {
"@eslint/js": "^9.9.0",
"@tanstack/router-devtools": "^1.52.3",
"@tanstack/router-plugin": "^1.52.0",
"@types/node": "^22.5.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
Expand Down
49 changes: 0 additions & 49 deletions src/App.tsx

This file was deleted.

45 changes: 40 additions & 5 deletions src/components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
import { Button, Code, Divider, Drawer, DrawerProps, Stack, Switch, Text, Title, useMantineColorScheme } from '@mantine/core'
import { Button, Code, Divider, Drawer, DrawerProps, NavLink, NavLinkProps, Stack, Switch, Text, Title, useMantineColorScheme } from '@mantine/core'
import { Link, LinkProps, useMatchRoute } from '@tanstack/react-router'

import { MoonStarsIcon, SunIcon } from '@/assets'
import { useWordleStore } from '@/hooks'
import { useSwipe, useWordleStore } from '@/hooks'
import { secondsToHms } from '@/utils'

interface SidebarProps extends DrawerProps {

}

const NavRouterLink = ({ label, to, ...props }: LinkProps & NavLinkProps) => {
const matchRoute = useMatchRoute()

return (
<NavLink
active={!!matchRoute({ to })}
component={Link}
to={to}
label={label}
rightSection={
<span style={{ fontFamily: 'monospace' }}>{'>'}</span>
}
{...props}
/>
)
}

const Sidebar = ({ opened, onClose, ...props }: SidebarProps) => {
const { colorScheme, toggleColorScheme } = useMantineColorScheme()
const [
resetStore,
time,
] = useWordleStore((state) => [
state.resetStore,
state.time,
])
const { colorScheme, toggleColorScheme } = useMantineColorScheme()

useSwipe({
left: onClose
})

const handleResetStore = () => {
resetStore()
Expand All @@ -35,8 +57,6 @@ const Sidebar = ({ opened, onClose, ...props }: SidebarProps) => {
Session Time: <Code fz='sm'>{secondsToHms(time)}</Code>
</Text>

<Divider />

<Switch
color='dark.4'
label='Dark mode'
Expand All @@ -47,6 +67,21 @@ const Sidebar = ({ opened, onClose, ...props }: SidebarProps) => {
offLabel={<SunIcon strokeWidth={2.5} width='1rem' color='var(--mantine-color-yellow-7)' />}
/>

<Divider />

<Stack gap={0}>
<NavRouterLink
to='/'
label='Wordle'
/>
<NavRouterLink
to='/helper'
label='Helper'
/>
</Stack>

<Divider />

<Button onClick={handleResetStore}>
Restart Game
</Button>
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as useWordleStore } from './store'
export { useSwipe } from './swipe'
60 changes: 60 additions & 0 deletions src/hooks/swipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useEffect, useRef } from 'react'

interface SwipeOptions {
left?: () => void
right?: () => void
up?: () => void
down?: () => void
}

const useSwipe = ({ left, right, up, down }: SwipeOptions = {}) => {
const touchCoordsRef = useRef({ touchStart: { x: 0, y: 0, time: Date.now() } })
const fnsRef = useRef({ up, down, left, right })
fnsRef.current = {
up,
left,
down,
right,
}
useEffect(() => {
const handleTouchStart = (e: TouchEvent) => {
touchCoordsRef.current.touchStart.x = e.targetTouches[0].clientX
touchCoordsRef.current.touchStart.y = e.targetTouches[0].clientY
touchCoordsRef.current.touchStart.time = Date.now()
}
const handleTouchEnd = (e: TouchEvent) => {
const threshold = 150
const swipeSpeed = 1 // sec;
const touchEndX = e.changedTouches[0].clientX
const touchEndY = e.changedTouches[0].clientY
const touchStartX = touchCoordsRef.current.touchStart.x
const touchStartY = touchCoordsRef.current.touchStart.y
const elapsedTime = (Date.now() - touchCoordsRef.current.touchStart.time) / 1000
if (elapsedTime > swipeSpeed) {
return
}
const xDistance = touchStartX - touchEndX
const yDistance = touchStartY - touchEndY

if (Math.abs(xDistance) < threshold && Math.abs(yDistance) < threshold) {
return
}

if (Math.abs(xDistance) >= Math.abs(yDistance)) {
xDistance > 0 ? fnsRef.current.left?.() : fnsRef.current.right?.()
} else {
yDistance > 0 ? fnsRef.current.down?.() : fnsRef.current.up?.()
}
}
window.addEventListener('touchstart', handleTouchStart)
window.addEventListener('touchend', handleTouchEnd)
return () => {
window.removeEventListener('touchstart', handleTouchStart)
window.removeEventListener('touchend', handleTouchEnd)
}
})
}

export {
useSwipe
}
6 changes: 6 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ body {
touch-action: pan-x pan-y;
padding: 0 0;
}

.mantine-NavLink-root[data-active] {
border-left: 1px solid var(--mantine-primary-color-light-color);
font-weight: 500;
color: var(--mantine-color-default-color);
}
45 changes: 6 additions & 39 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,16 @@
import '@mantine/core/styles.css'
import '@mantine/notifications/styles.css'
import './index.css'

import { CSSVariablesResolver, MantineProvider, createTheme, localStorageColorSchemeManager } from '@mantine/core'
import { MantineProvider } from '@mantine/core'
import { Notifications } from '@mantine/notifications'
import { RouterProvider } from '@tanstack/react-router'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

import App from './App.tsx'
import './index.css'

const colorSchemeManager = localStorageColorSchemeManager({
key: 'better-wordle-color-scheme',
})

const cssResolver: CSSVariablesResolver = (theme) => ({
variables: {
'--color-letter-state-perfect': theme.colors.green[9],
'--color-letter-state-correct': theme.colors.yellow[9],
'--color-letter-state-incorrect': theme.colors.gray[8],
'--color-letter-state-incorrect-light': 'var(--mantine-color-dimmed)',
},

light: {
'--mantine-color-body': theme.colors.gray[1],
'--color-letter-state-incorrect': theme.colors.gray[7],
'--color-letter-filled-border': 'color-mix(in srgb, var(--mantine-color-default-border), #000 20%)',
'--color-letter-selected': theme.colors.gray[3],
},

dark: {
'--color-letter-filled-border': 'color-mix(in srgb, var(--mantine-color-default-border), #fff 20%)',
'--color-letter-selected': theme.colors.gray[7],
},
})
import router from './router'
import { colorSchemeManager, cssResolver, theme } from './theme'

const theme = createTheme({
components: {
Code: {
defaultProps: {
bg: 'gray',
c: 'var(--mantine-primary-color-contrast)',
}
}
}
})

createRoot(document.getElementById('root')!).render(
<StrictMode>
Expand All @@ -57,7 +24,7 @@ createRoot(document.getElementById('root')!).render(
autoClose={3000}
limit={2}
/>
<App />
<RouterProvider router={router} />
</MantineProvider>
</StrictMode>
)
74 changes: 74 additions & 0 deletions src/routeTree.gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* prettier-ignore-start */

/* eslint-disable */

// @ts-nocheck

// noinspection JSUnusedGlobalSymbols

// This file is auto-generated by TanStack Router

// Import Routes

import { Route as rootRoute } from './routes/__root'
import { Route as HelperImport } from './routes/helper'
import { Route as IndexImport } from './routes/index'

// Create/Update Routes

const HelperRoute = HelperImport.update({
path: '/helper',
getParentRoute: () => rootRoute,
} as any)

const IndexRoute = IndexImport.update({
path: '/',
getParentRoute: () => rootRoute,
} as any)

// Populate the FileRoutesByPath interface

declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexImport
parentRoute: typeof rootRoute
}
'/helper': {
id: '/helper'
path: '/helper'
fullPath: '/helper'
preLoaderRoute: typeof HelperImport
parentRoute: typeof rootRoute
}
}
}

// Create and export the route tree

export const routeTree = rootRoute.addChildren({ IndexRoute, HelperRoute })

/* prettier-ignore-end */

/* ROUTE_MANIFEST_START
{
"routes": {
"__root__": {
"filePath": "__root.tsx",
"children": [
"/",
"/helper"
]
},
"/": {
"filePath": "index.tsx"
},
"/helper": {
"filePath": "helper.tsx"
}
}
}
ROUTE_MANIFEST_END */
17 changes: 17 additions & 0 deletions src/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'


const router = createRouter({
routeTree,
basepath: '/better-wordle',
trailingSlash: 'never',
})

declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}

export default router
Loading

0 comments on commit 89e2139

Please sign in to comment.