Fonts & theme toggle component

This commit is contained in:
Ahmed Al-Taiar
2024-08-07 23:58:43 -04:00
parent 14c20d4315
commit 35548bf37a
10 changed files with 158 additions and 13 deletions

View File

@ -6,7 +6,7 @@
# https://redwoodjs.com/docs/app-configuration-redwood-toml
[web]
title = "Redwood App"
title = "Ahmed Al-Taiar"
port = 8910
apiUrl = "/.redwood/functions" # You can customize graphql and dbauth urls individually too: see https://redwoodjs.com/docs/app-configuration-redwood-toml#api-paths
includeEnvironmentVariables = [

View File

@ -1,10 +1,13 @@
/** @type {import('tailwindcss').Config} */
export const content = ['src/**/*.{js,jsx,ts,tsx}']
export const theme = {
extend: {},
extend: {
fontFamily: {
syne: ['Syne', 'sans-serif'],
inter: ['Inter', 'sans-serif'],
},
},
}
export const plugins = [require('daisyui')]
export const daisyui = { themes: ['light', 'dark'] }

View File

@ -12,6 +12,7 @@ import { Router, Route } from '@redwoodjs/router'
const Routes = () => {
return (
<Router>
<Route path="/" page={HomePage} name="home" />
<Route notfound page={NotFoundPage} />
</Router>
)

View File

@ -0,0 +1,26 @@
// Pass props to your component by passing an `args` object to your story
//
// ```tsx
// export const Primary: Story = {
// args: {
// propName: propValue
// }
// }
// ```
//
// See https://storybook.js.org/docs/react/writing-stories/args.
import type { Meta, StoryObj } from '@storybook/react'
import ThemeToggle from './ThemeToggle'
const meta: Meta<typeof ThemeToggle> = {
component: ThemeToggle,
tags: ['autodocs'],
}
export default meta
type Story = StoryObj<typeof ThemeToggle>
export const Primary: Story = {}

View File

@ -0,0 +1,14 @@
import { render } from '@redwoodjs/testing/web'
import ThemeToggle from './ThemeToggle'
// Improve this test with help from the Redwood Testing Doc:
// https://redwoodjs.com/docs/testing#testing-components
describe('ThemeToggle', () => {
it('renders successfully', () => {
expect(() => {
render(<ThemeToggle />)
}).not.toThrow()
})
})

View File

@ -0,0 +1,47 @@
import { useState, useEffect } from 'react'
import { mdiWeatherSunny, mdiWeatherNight } from '@mdi/js'
import Icon from '@mdi/react'
const ThemeToggle = () => {
const [theme, setTheme] = useState(
localStorage.getItem('theme') ? localStorage.getItem('theme') : 'light'
)
const handleToggle = (e) => {
if (e.target.checked) {
setTheme('dark')
} else {
setTheme('light')
}
}
useEffect(() => {
localStorage.setItem('theme', theme)
document
.querySelector('html')
.setAttribute('data-theme', localStorage.getItem('theme'))
}, [theme])
return (
// eslint-disable-next-line jsx-a11y/label-has-associated-control
<label className="btn btn-ghost swap swap-rotate w-12">
<input
type="checkbox"
className="theme-controller"
checked={theme === 'dark'}
onChange={handleToggle}
/>
<Icon
path={mdiWeatherSunny}
className="swap-off h-8 w-8 text-yellow-500"
/>
<Icon path={mdiWeatherNight} className="swap-on h-8 w-8 text-blue-500" />
</label>
)
}
export default ThemeToggle

View File

@ -1,15 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" href="/favicon.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter&family=Syne"
rel="stylesheet"
/>
</head>
<body>
<!-- Please keep this div empty -->
<div id="redwood-app"></div>
</body>
</html>

View File

@ -0,0 +1,13 @@
import type { Meta, StoryObj } from '@storybook/react'
import HomePage from './HomePage'
const meta: Meta<typeof HomePage> = {
component: HomePage,
}
export default meta
type Story = StoryObj<typeof HomePage>
export const Primary: Story = {}

View File

@ -0,0 +1,14 @@
import { render } from '@redwoodjs/testing/web'
import HomePage from './HomePage'
// Improve this test with help from the Redwood Testing Doc:
// https://redwoodjs.com/docs/testing#testing-pages-layouts
describe('HomePage', () => {
it('renders successfully', () => {
expect(() => {
render(<HomePage />)
}).not.toThrow()
})
})

View File

@ -0,0 +1,21 @@
import { Link, routes } from '@redwoodjs/router'
import { Metadata } from '@redwoodjs/web'
const HomePage = () => {
return (
<>
<Metadata title="Home" description="Home page" />
<h1>HomePage</h1>
<p>
Find me in <code>./web/src/pages/HomePage/HomePage.tsx</code>
</p>
<p>
My default route is named <code>home</code>, link to me with `
<Link to={routes.home()}>Home</Link>`
</p>
</>
)
}
export default HomePage