Skip to content

Commit

Permalink
sidebar with dark mode toggle+restart button; general theme cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
LooLzzz committed Aug 31, 2024
1 parent 4347cfd commit dee65c6
Show file tree
Hide file tree
Showing 25 changed files with 194 additions and 52 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 @@ -16,13 +16,15 @@
"@mantine/spotlight": "^7.12.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet": "^6.1.0",
"zustand": "^4.5.5"
},
"devDependencies": {
"@eslint/js": "^9.9.0",
"@types/node": "^22.5.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-helmet": "^6.1.11",
"@vitejs/plugin-react-swc": "^3.5.0",
"eslint": "^9.9.0",
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
Expand Down
49 changes: 39 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,51 @@
import { Box, Stack } from '@mantine/core'
import { Affix, Box, Burger, Stack, useComputedColorScheme } from '@mantine/core'
import { useDisclosure, useMediaQuery } from '@mantine/hooks'
import { Helmet } from 'react-helmet'

import { FloatingKeyboard, WordsGuesser } from '@/components'
import { FloatingKeyboard, Sidebar, WordsGuesser } from '@/components'

import classes from './App.module.scss'
import { useMediaQuery } from '@mantine/hooks'


function App() {
const isXs = useMediaQuery('(max-width: 400px)')
const colorScheme = useComputedColorScheme()
const isXs = useMediaQuery('(max-width: 440px)')
const [isSidebarOpened, { toggle: toggleSidebar, close: closeSidebar }] = useDisclosure(false)

return (
<Stack className={classes.stack} h='100%' align='center' justify='center' gap={isXs ? 30 : 50}>
<Box mah='60rem' style={{ justifySelf: 'start' }}>
<WordsGuesser />
</Box>
<>
<Helmet>
<meta name='theme-color' content={colorScheme === 'dark' ? '#242424' : '#f1f3f5'} />
</Helmet>

<FloatingKeyboard />
</Stack>
<Sidebar
opened={isSidebarOpened}
onClose={closeSidebar}
/>

<Affix
zIndex={0}
position={{
top: 10,
left: isXs ? undefined : 10,
right: isXs ? 10 : undefined,
}}
>
<Burger
opened={isSidebarOpened}
onClick={toggleSidebar}
opacity={0.6}
/>
</Affix>

<Stack className={classes.stack} h='100%' align='center' justify='center' gap={isXs ? 30 : 50}>
<Box mah='60rem' style={{ justifySelf: 'start' }}>
<WordsGuesser />
</Box>

<FloatingKeyboard />
</Stack>
</>
)
}

Expand Down
File renamed without changes
File renamed without changes
5 changes: 5 additions & 0 deletions src/assets/icons/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { default as BackspaceIcon } from './backspace.svg?react'
export { default as EnterIcon } from './enter.svg?react'
export { default as MoonStarsIcon } from './moonstars.svg?react'
export { default as SunIcon } from './sun.svg?react'
export { default as WordleIcon } from './wordle-icon.svg?react'
8 changes: 8 additions & 0 deletions src/assets/icons/moonstars.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/assets/icons/sun.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
17 changes: 2 additions & 15 deletions src/assets/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,2 @@
// @ts-ignore
export { default as BackspaceIcon } from './backspace.svg?react'
// @ts-ignore
export { default as EnterIcon } from './enter.svg?react'

import answerList from './answerlist.json'
import wordList from './wordlist.json'

const wordsSet = new Set<string>(wordList)
const answersSet = new Set<string>(answerList)

export {
answersSet,
wordsSet
}
export * from './icons'
export * from './wordle'
File renamed without changes.
13 changes: 13 additions & 0 deletions src/assets/wordle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import answerList from './answerlist.json'
import wordList from './wordlist.json'

const wordsSet = new Set<string>(wordList)
const answersSet = new Set<string>(answerList)

export {
answerList as answersList,
answersSet,
wordList as wordsList,
wordsSet
}

File renamed without changes.
15 changes: 15 additions & 0 deletions src/components/FloatingKeyboard/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,19 @@
&[data-active="true"] {
background-color: var(--mantine-color-body);
}

&[data-letter-state="perfect"] {
background-color: var(--color-letter-state-perfect);
color: var(--mantine-primary-color-contrast);
}

&[data-letter-state="correct"] {
background-color: var(--color-letter-state-correct);
color: var(--mantine-primary-color-contrast);
}

&[data-letter-state="incorrect"] {
background-color: var(--color-letter-state-incorrect-light);
color: var(--mantine-primary-color-contrast);
}
}
26 changes: 13 additions & 13 deletions src/components/FloatingKeyboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ const FloatingKeyboard = () => {
)
), [answer, guesses])

const generateLetterBg = (letter: string) => {
const getLetterState = (letter: string) => {
if (perfectLetters.has(letter)) {
return 'var(--mantine-color-green-9)'
return 'perfect'
} else if (correctLetters.has(letter)) {
return 'var(--mantine-color-yellow-9)'
return 'correct'
} else if (deadLetters.has(letter)) {
return 'var(--mantine-color-dimmed)'
return 'incorrect'
} else {
return undefined
}
Expand Down Expand Up @@ -108,21 +108,21 @@ const FloatingKeyboard = () => {
keyboardRows.map((row, idx) => (
<Group key={idx} gap={5}>
{
row.map((key) => (
row.map((letter) => (
<Kbd
key={key}
ref={keyRefs[key]}
key={letter}
ref={keyRefs[letter]}
className={classes.kbd}
bg={generateLetterBg(key)}
onClick={() => handleClick(key)}
tt={key.length === 1 ? 'uppercase' : undefined}
onClick={() => handleClick(letter)}
tt={letter.length === 1 ? 'uppercase' : undefined}
data-letter-state={getLetterState(letter)}
>
{
key === 'Backspace'
letter === 'Backspace'
? <BackspaceIcon style={{ transform: 'translateY(0.25rem)' }} />
: key === 'Enter'
: letter === 'Enter'
? <EnterIcon style={{ transform: 'translateY(0.3rem)' }} />
: key
: letter
}
</Kbd>
))
Expand Down
48 changes: 48 additions & 0 deletions src/components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Button, Divider, Drawer, DrawerProps, Stack, Switch, Title, useMantineColorScheme } from '@mantine/core'

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

interface SidebarProps extends DrawerProps {

}

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

const handleResetStore = () => {
resetStore()
onClose()
}

return (
<Drawer
opened={opened}
onClose={onClose}
title={<Title order={2}>Settings</Title>}
{...props}
>
<Stack>
<Switch
color='dark.4'
label='Dark mode'
size='md'
checked={colorScheme === 'dark'}
onChange={toggleColorScheme}
onLabel={<MoonStarsIcon strokeWidth={2.5} width='1rem' color='var(--mantine-color-blue-6)' />}
offLabel={<SunIcon strokeWidth={2.5} width='1rem' color='var(--mantine-color-yellow-7)' />}
/>
<Divider />
<Button onClick={handleResetStore}>
Restart Game
</Button>
</Stack>
</Drawer>
)
}

export {
Sidebar as default,
type SidebarProps
}
16 changes: 9 additions & 7 deletions src/components/WordsGuesser/Guess/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ $reveal-anim-timing-function: ease-in-out;
height: 5rem;
border: 1px solid var(--mantine-color-default-border);
text-transform: uppercase;
transition-property: background-color, border-color;
transition-property: background-color, border-color, color;
transition-duration: 150ms;

@media screen and (max-width: 768px) {
Expand All @@ -45,15 +45,18 @@ $reveal-anim-timing-function: ease-in-out;
}

&[data-letter-state="perfect"] {
background-color: var(--mantine-color-green-9);
background-color: var(--color-letter-state-perfect);
color: var(--mantine-primary-color-contrast);
}

&[data-letter-state="correct"] {
background-color: var(--mantine-color-yellow-9);
background-color: var(--color-letter-state-correct);
color: var(--mantine-primary-color-contrast);
}

&[data-letter-state="incorrect"] {
background-color: var(--mantine-color-gray-8);
background-color: var(--color-letter-state-incorrect);
color: var(--mantine-primary-color-contrast);
}
}

Expand All @@ -72,11 +75,10 @@ $reveal-anim-timing-function: ease-in-out;
}

&.guessedLetter {
border-color: color-mix(in srgb, var(--mantine-color-default-border), #fff 20%);
// border-color: var(--mantine-color-gray-7);
border-color: var(--color-letter-filled-border);
}

&.selected {
background-color: var(--mantine-color-gray-7) !important;
background-color: var(--color-letter-selected) !important;
}
}
3 changes: 0 additions & 3 deletions src/components/WordsGuesser/Guess/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,13 @@ const Guess = ({

if (letter === answer.slice(idx, idx + 1)) {
return 'perfect'
// return 'var(--mantine-color-green-9)'
}

if (answerLetters.includes(letter)) {
return 'correct'
// return 'var(--mantine-color-yellow-9)'
}

return 'incorrect'
// return 'var(--mantine-color-gray-8)'
}, [answer, answerLetters, active, isEmptyGuess])

return (
Expand Down
1 change: 1 addition & 0 deletions src/components/WordsGuesser/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const WordsGuesser = () => {
}
}
}
e.preventDefault()
break

case 'Backspace':
Expand Down
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as FloatingKeyboard } from './FloatingKeyboard'
export { default as Sidebar, type SidebarProps } from './Sidebar'
export { default as WordsGuesser } from './WordsGuesser'
4 changes: 2 additions & 2 deletions src/hooks/store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'

import answerList from '@/assets/answerlist.json'
import { answersList } from '@/assets'

interface WordleState {
answer: string
Expand All @@ -17,7 +17,7 @@ interface WordleState {
}


const generateRandomWord = () => answerList[Math.floor(Math.random() * answerList.length)]
const generateRandomWord = () => answersList[Math.floor(Math.random() * answersList.length)]

const initialState: Pick<WordleState, 'answer' | 'guesses' | 'currentGuess'> = {
answer: null as any,
Expand Down
1 change: 1 addition & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ body {
}

#root {
transition: background-color 350ms ease;
height: 100dvh;
touch-action: pan-x pan-y;
padding: 0 0;
Expand Down
24 changes: 23 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '@mantine/core/styles.css'
import '@mantine/notifications/styles.css'

import { MantineProvider, createTheme, localStorageColorSchemeManager } from '@mantine/core'
import { CSSVariablesResolver, MantineProvider, createTheme, localStorageColorSchemeManager } from '@mantine/core'
import { Notifications } from '@mantine/notifications'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
Expand All @@ -13,6 +13,27 @@ 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],
},
})

const theme = createTheme({

})
Expand All @@ -22,6 +43,7 @@ createRoot(document.getElementById('root')!).render(
<MantineProvider
defaultColorScheme='dark'
colorSchemeManager={colorSchemeManager}
cssVariablesResolver={cssResolver}
theme={theme}
>
<Notifications
Expand Down
Loading

0 comments on commit dee65c6

Please sign in to comment.