Skip to content

Commit baaad94

Browse files
committed
csr-daisyui: form example, mobile navigation
1 parent 0db20a9 commit baaad94

File tree

12 files changed

+118
-72
lines changed

12 files changed

+118
-72
lines changed

packages/csr-daisyui/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# React Router Starter
22

3-
See [./app/md-content/home.en.md](public/md-content/home.en.md) for a detailed description of the project.
3+
See [./public/md-content/home.en.md](public/md-content/home.en.md) for a detailed description of the project.

packages/csr-daisyui/app/App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react'
22
import { BrowserRouter as Router, Route, Routes } from 'react-router'
3+
import { Layout } from './components/theme/layout.tsx'
34
import { ConfigProvider } from './contexts/config-provider.tsx'
45

56
import { CatchAll404 } from './routes/catch-all-404.tsx'
67
import { Home } from './routes/home.tsx'
7-
import { Layout } from './routes/layout.tsx'
88
import { DevModeOverlay } from '~/components/devmode-overlay.tsx'
99
import { FormExample } from '~/routes/form-example.tsx'
1010
import { Legal } from '~/routes/legal.tsx'
@@ -17,6 +17,7 @@ export const App = () => {
1717
<Layout>
1818
<Routes>
1919
<Route path="/" element={<Home />} />
20+
<Route path="/home" element={<Home />} />
2021
<Route path="/form" element={<FormExample />} />
2122
<Route path="/legal" element={<Legal />} />
2223
<Route path="/privacy" element={<Privacy />} />

packages/csr-daisyui/app/components/theme/footer.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ export const Footer: React.FC = () => {
1616
section: t('menu.footer.section.products', 'Products'),
1717
items: [
1818
{
19-
path: (lang: string) => href('/:lang?/home', { lang }),
19+
path: (lang: string) => href('/home', { lang }),
2020
name: t('menu.home.name', 'Home'),
2121
},
2222
{
23-
path: (lang: string) => href('/:lang?/form', { lang }),
23+
path: (lang: string) => href('/form', { lang }),
2424
name: t('menu.form.name', 'Example Form'),
2525
},
2626
],
@@ -29,11 +29,11 @@ export const Footer: React.FC = () => {
2929
section: t('menu.footer.section.company', 'Company'),
3030
items: [
3131
{
32-
path: (lang: string) => href('/:lang?/home', { lang }),
32+
path: (lang: string) => href('/home', { lang }),
3333
name: t('menu.home.name', 'Home'),
3434
},
3535
{
36-
path: (lang: string) => href('/:lang?/form', { lang }),
36+
path: (lang: string) => href('/form', { lang }),
3737
name: t('menu.form.name', 'Example Form'),
3838
},
3939
],
@@ -42,11 +42,11 @@ export const Footer: React.FC = () => {
4242
section: t('menu.footer.section.resources', 'Resources'),
4343
items: [
4444
{
45-
path: (lang: string) => href('/:lang?/home', { lang }),
45+
path: (lang: string) => href('/home', { lang }),
4646
name: t('menu.home.name', 'Home'),
4747
},
4848
{
49-
path: (lang: string) => href('/:lang?/form', { lang }),
49+
path: (lang: string) => href('/form', { lang }),
5050
name: t('menu.form.name', 'Example Form'),
5151
},
5252
],
@@ -111,10 +111,10 @@ export const Footer: React.FC = () => {
111111
})}
112112
</div>
113113
<div className="flex flex-wrap gap-x-6 gap-y-2">
114-
<Link to={href('/:lang?/legal')} className="hover:underline">
114+
<Link to={href('/legal')} className="hover:underline">
115115
{t('theme.footer.legalLink', 'Legal information')}
116116
</Link>
117-
<Link to={href('/:lang?/privacy')} className="hover:underline">
117+
<Link to={href('/privacy')} className="hover:underline">
118118
{t('theme.footer.privacyLink', 'Privacy Policy')}
119119
</Link>
120120
</div>

packages/csr-daisyui/app/components/theme/header.tsx

Lines changed: 0 additions & 44 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Container } from '~/components/theme/container.tsx'
2+
import { NavDrawer } from '~/components/theme/header/nav-drawer.tsx'
3+
4+
export const Header: React.FC = () => {
5+
return (
6+
<Container as="header" className="py-0 md:py-4">
7+
<NavDrawer />
8+
</Container>
9+
)
10+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { MenuIcon } from 'lucide-react'
2+
import React from 'react'
3+
import { useTranslation } from 'react-i18next'
4+
import { href, Link } from 'react-router'
5+
import { Logo } from '~/components/theme/logo.tsx'
6+
import { useLang } from '~/hooks/use-lang.tsx'
7+
import { type MenuItem } from '~/types/menu-item.ts'
8+
9+
export const NavDrawer: React.FC = () => {
10+
const id = React.useId()
11+
const { t } = useTranslation()
12+
const { lang } = useLang()
13+
const [isOpen, setIsOpen] = React.useState(false)
14+
15+
const open = () => setIsOpen(true)
16+
const close = () => setIsOpen(false)
17+
const toggle = () => setIsOpen((prev) => !prev)
18+
19+
const menu: MenuItem[] = [
20+
{
21+
path: (lang: string) => href('/home', { lang }),
22+
name: t('menu.home.name', 'Home'),
23+
},
24+
{
25+
path: (lang: string) => href('/form', { lang }),
26+
name: t('menu.form.name', 'Example Form'),
27+
},
28+
]
29+
30+
return (
31+
<div className="drawer">
32+
<input id={id} type="checkbox" className="drawer-toggle" checked={isOpen} onChange={toggle} />
33+
<div className="drawer-content flex flex-col">
34+
<div className="navbar bg-base-300 flex w-full">
35+
<div className="flex-none lg:hidden">
36+
<button onClick={toggle} aria-label="open sidebar" className="btn btn-square btn-ghost">
37+
<MenuIcon />
38+
</button>
39+
</div>
40+
<div className="mx-2 flex-1 justify-items-end px-2 md:justify-items-start">
41+
<Link to={href('/')} className="btn btn-ghost btn-sm flex flex-row gap-3 text-xl">
42+
<Logo variant="sm" />
43+
<span>{t('header.title', 'ACME Inc.')}</span>
44+
</Link>
45+
</div>
46+
<div className="hidden flex-none lg:block">
47+
<ul className="menu menu-horizontal">
48+
{menu?.map((each, idx) => (
49+
<li key={idx}>
50+
<Link to={each.path(lang)}>{t(each.name)}</Link>
51+
</li>
52+
))}
53+
</ul>
54+
</div>
55+
</div>
56+
</div>
57+
<div className="drawer-side z-10">
58+
<label
59+
htmlFor={id}
60+
aria-label="close sidebar"
61+
className="drawer-overlay"
62+
onClick={close}></label>
63+
<ul className="menu bg-base-200 min-h-full w-80 p-4">
64+
{menu?.map((each, idx) => (
65+
<li key={idx}>
66+
<Link to={each.path(lang)} onClick={close}>
67+
{t(each.name)}
68+
</Link>
69+
</li>
70+
))}
71+
</ul>
72+
</div>
73+
</div>
74+
)
75+
}

packages/csr-daisyui/app/routes/layout.tsx renamed to packages/csr-daisyui/app/components/theme/layout.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { type PropsWithChildren } from 'react'
22
import { Container } from '~/components/theme/container.tsx'
33
import { Footer } from '~/components/theme/footer.tsx'
4-
import { Header } from '~/components/theme/header.tsx'
4+
import { Header } from '~/components/theme/header/header.tsx'
55

66
export const Layout: React.FC<PropsWithChildren> = ({ children }) => {
77
return (
88
<>
99
<Header />
1010
<Container>
11-
<div className="divider"></div>
11+
<div className="divider my-0 md:my-4"></div>
1212
</Container>
13-
<Container className="gap-0 py-12">{children}</Container>
13+
<Container className="gap-0 py-3 md:py-12">{children}</Container>
1414
<Footer />
1515
</>
1616
)

packages/csr-daisyui/app/routes/form-example.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { zodResolver } from '@hookform/resolvers/zod'
22
import React from 'react'
33
import { useTranslation } from 'react-i18next'
4-
import { Form } from 'react-router'
5-
import { useRemixForm } from 'remix-hook-form'
4+
import { useForm } from 'react-hook-form'
65
import { z } from 'zod'
76
import { Container } from '~/components/theme/container.tsx'
87
import { H1 } from '~/components/typography/h1.tsx'
@@ -18,22 +17,27 @@ const schema = z.object({
1817
})
1918

2019
type FormData = z.infer<typeof schema>
21-
const resolver = zodResolver(schema)
2220

2321
export const FormExample: React.FC = () => {
2422
const { t } = useTranslation()
2523
const {
2624
handleSubmit,
2725
formState: { errors },
2826
register,
29-
} = useRemixForm<FormData>({
27+
} = useForm<FormData>({
3028
mode: 'onSubmit',
31-
resolver,
29+
resolver: zodResolver(schema),
3230
})
31+
32+
const onSubmit = (data: FormData) => {
33+
console.log(data)
34+
// Handle form submission here
35+
}
36+
3337
return (
3438
<Container>
3539
<H1>{t('routes.form.title', 'Example Form with Validation')}</H1>
36-
<Form onSubmit={handleSubmit} method="POST" className="flex max-w-2xl flex-col gap-3">
40+
<form onSubmit={handleSubmit(onSubmit)} className="flex max-w-2xl flex-col gap-3">
3741
<Input
3842
{...register('name')}
3943
type="text"
@@ -66,7 +70,7 @@ export const FormExample: React.FC = () => {
6670
<Button type="submit" variant="primary">
6771
{t('userActions.button.submit', 'Submit Form')}
6872
</Button>
69-
</Form>
73+
</form>
7074
</Container>
7175
)
7276
}

packages/csr-daisyui/app/styles/tailwind.css

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
--size-field: 0.3125rem;
3838
--border: 0.5px;
3939
--depth: 1;
40-
--noise: 0;
4140
}
4241

4342

@@ -73,7 +72,6 @@
7372
--size-field: 0.3125rem;
7473
--border: 0.5px;
7574
--depth: 1;
76-
--noise: 0;
7775
--root-bg: var(--color-base-300);
7876
}
7977

packages/csr-daisyui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"lucide-react": "^0.487.0",
3838
"react": "^19.1.0",
3939
"react-dom": "^19.1.0",
40+
"react-hook-form": "^7.55.0",
4041
"react-i18next": "^15.4.1",
4142
"react-router": "7.4.1",
4243
"swr": "^2.3.3",

0 commit comments

Comments
 (0)