init project
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled

This commit is contained in:
how2ice
2025-12-12 14:26:25 +09:00
commit 005cf56baf
43188 changed files with 1079531 additions and 0 deletions

35
examples/joy-ui-nextjs-ts/.gitignore vendored Normal file
View File

@@ -0,0 +1,35 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

View File

@@ -0,0 +1,45 @@
# Joy UI - Next.js App Router with TypeScript
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/HEAD/packages/create-next-app).
## How to use
Download the example [or clone the repo](https://github.com/mui/material-ui):
<!-- #target-branch-reference -->
```bash
curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/joy-ui-nextjs-ts
cd joy-ui-nextjs-ts
```
Install it and run:
```bash
npm install
npm run dev
```
Open [http://localhost:3000](http://localhost:3000) with your web browser to see the result.
or:
<!-- #target-branch-reference -->
[![Edit on StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mui/material-ui/tree/master/examples/joy-ui-nextjs-ts)
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/github/mui/material-ui/tree/master/examples/joy-ui-nextjs-ts)
## Learn more
To learn more about this example:
- [Next.js documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Customizing Joy UI](https://mui.com/joy-ui/customization/approaches/) - approaches to customizing Joy UI.
## What's next?
<!-- #host-reference -->
You now have a working example project.
You can head back to the documentation and continue by browsing the [templates](https://mui.com/joy-ui/getting-started/templates/) section.

View File

@@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
export default nextConfig;

View File

@@ -0,0 +1,29 @@
{
"name": "joy-ui-nextjs-ts",
"version": "5.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"post-update": "echo \"codesandbox preview only, need an update\" && pnpm update --latest"
},
"dependencies": {
"@emotion/cache": "latest",
"@emotion/react": "latest",
"@emotion/styled": "latest",
"@mui/joy": "next",
"next": "latest",
"react": "latest",
"react-dom": "latest"
},
"devDependencies": {
"@types/node": "latest",
"@types/react": "latest",
"@types/react-dom": "latest",
"eslint": "latest",
"eslint-config-next": "latest",
"typescript": "latest"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,17 @@
import * as React from 'react';
import ThemeRegistry from '@/components/ThemeRegistry/ThemeRegistry';
export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};
export default function RootLayout(props: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<ThemeRegistry>{props.children}</ThemeRegistry>
</body>
</html>
);
}

View File

@@ -0,0 +1,63 @@
import * as React from 'react';
import Sheet from '@mui/joy/Sheet';
import Typography from '@mui/joy/Typography';
import FormControl from '@mui/joy/FormControl';
import FormLabel from '@mui/joy/FormLabel';
import Input from '@mui/joy/Input';
import Button from '@mui/joy/Button';
import Link from '@mui/joy/Link';
export default function Home() {
return (
<Sheet
sx={{
display: 'flex',
flexFlow: 'row nowrap',
justifyContent: 'center',
alignItems: 'center',
minHeight: '100vh',
}}
>
<Sheet
sx={{
width: 300,
mx: 'auto',
my: 4,
py: 3,
px: 2,
display: 'flex',
flexDirection: 'column',
gap: 2,
borderRadius: 'sm',
boxShadow: 'md',
}}
variant="outlined"
>
<div>
<Typography level="h4" component="h1">
<strong>Welcome back 👋</strong>
</Typography>
<Typography level="body-sm">Sign in to continue.</Typography>
</div>
<FormControl id="email">
<FormLabel>Email</FormLabel>
<Input name="email" type="email" placeholder="johndoe@email.com" />
</FormControl>
<FormControl id="password">
<FormLabel>Password</FormLabel>
<Input name="password" type="password" placeholder="password" />
</FormControl>
<Button sx={{ mt: 1 }}>Log in</Button>
<Typography
endDecorator={<Link href="/sign-up">Sign up</Link>}
sx={{
fontSize: 'sm',
alignSelf: 'center',
}}
>
Don&apos;t have an account?
</Typography>
</Sheet>
</Sheet>
);
}

View File

@@ -0,0 +1,64 @@
import * as React from 'react';
import Sheet from '@mui/joy/Sheet';
import Typography from '@mui/joy/Typography';
import FormControl from '@mui/joy/FormControl';
import FormLabel from '@mui/joy/FormLabel';
import Input from '@mui/joy/Input';
import Button from '@mui/joy/Button';
import Link from '@mui/joy/Link';
export default function SignUp() {
return (
<Sheet
sx={{
display: 'flex',
flexFlow: 'row nowrap',
justifyContent: 'center',
alignItems: 'center',
minHeight: '100vh',
}}
>
<Sheet
sx={{
width: 300,
mx: 'auto',
my: 4,
py: 3,
px: 2,
display: 'flex',
flexDirection: 'column',
gap: 2,
borderRadius: 'sm',
boxShadow: 'md',
}}
variant="outlined"
>
<div>
<Typography level="h4" component="h1">
<strong>Welcome 👋</strong>
</Typography>
<Typography level="body-sm">Sign up for an account.</Typography>
</div>
<FormControl>
<FormLabel>Email</FormLabel>
<Input name="email" type="email" placeholder="johndoe@email.com" />
</FormControl>
<FormControl>
<FormLabel>Password</FormLabel>
<Input name="password" type="password" placeholder="password" />
</FormControl>
<Button sx={{ mt: 1 }}>Create account</Button>
<Typography
endDecorator={<Link href="/">Log in</Link>}
sx={{
fontSize: 'sm',
alignSelf: 'center',
}}
>
Already have an account?
</Typography>
</Sheet>
</Sheet>
);
}

View File

@@ -0,0 +1,91 @@
'use client';
import * as React from 'react';
import createCache from '@emotion/cache';
import { useServerInsertedHTML } from 'next/navigation';
import { CacheProvider as DefaultCacheProvider } from '@emotion/react';
import type { EmotionCache, Options as OptionsOfCreateCache } from '@emotion/cache';
export type NextAppDirEmotionCacheProviderProps = {
/** This is the options passed to createCache() from 'import createCache from "@emotion/cache"' */
options: Omit<OptionsOfCreateCache, 'insertionPoint'>;
/** By default <CacheProvider /> from 'import { CacheProvider } from "@emotion/react"' */
CacheProvider?: React.ElementType<{ value: EmotionCache }>;
children: React.ReactNode;
};
// Adapted from https://github.com/garronej/tss-react/blob/main/src/next/appDir.tsx
export default function NextAppDirEmotionCacheProvider(props: NextAppDirEmotionCacheProviderProps) {
const { options, CacheProvider = DefaultCacheProvider, children } = props;
const [registry] = React.useState(() => {
const cache = createCache(options);
cache.compat = true;
const prevInsert = cache.insert;
let inserted: { name: string; isGlobal: boolean }[] = [];
cache.insert = (...args) => {
const [selector, serialized] = args;
if (cache.inserted[serialized.name] === undefined) {
inserted.push({
name: serialized.name,
isGlobal: !selector,
});
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
useServerInsertedHTML(() => {
const inserted = registry.flush();
if (inserted.length === 0) {
return null;
}
let styles = '';
let dataEmotionAttribute = registry.cache.key;
const globals: {
name: string;
style: string;
}[] = [];
inserted.forEach(({ name, isGlobal }) => {
const style = registry.cache.inserted[name];
if (typeof style !== 'boolean') {
if (isGlobal) {
globals.push({ name, style });
} else {
styles += style;
dataEmotionAttribute += ` ${name}`;
}
}
});
return (
<React.Fragment>
{globals.map(({ name, style }) => (
<style
key={name}
data-emotion={`${registry.cache.key}-global ${name}`}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style }}
/>
))}
{styles && (
<style
data-emotion={dataEmotionAttribute}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: styles }}
/>
)}
</React.Fragment>
);
});
return <CacheProvider value={registry.cache}>{children}</CacheProvider>;
}

View File

@@ -0,0 +1,17 @@
'use client';
import * as React from 'react';
import { CssVarsProvider } from '@mui/joy/styles';
import CssBaseline from '@mui/joy/CssBaseline';
import NextAppDirEmotionCacheProvider from './EmotionCache';
import theme from './theme';
export default function ThemeRegistry({ children }: { children: React.ReactNode }) {
return (
<NextAppDirEmotionCacheProvider options={{ key: 'joy' }}>
<CssVarsProvider theme={theme}>
<CssBaseline />
{children}
</CssVarsProvider>
</NextAppDirEmotionCacheProvider>
);
}

View File

@@ -0,0 +1,47 @@
import { extendTheme } from '@mui/joy/styles';
import { Inter, Source_Code_Pro } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
adjustFontFallback: false, // prevent NextJS from adding its own fallback font
fallback: ['var(--joy-fontFamily-fallback)'], // use Joy UI's fallback font
display: 'swap',
});
const sourceCodePro = Source_Code_Pro({
subsets: ['latin'],
adjustFontFallback: false, // prevent NextJS from adding its own fallback font
fallback: [
// the default theme's fallback for monospace fonts
'ui-monospace',
'SFMono-Regular',
'Menlo',
'Monaco',
'Consolas',
'Liberation Mono',
'Courier New',
'monospace',
],
display: 'swap',
});
const theme = extendTheme({
fontFamily: {
body: inter.style.fontFamily,
display: inter.style.fontFamily,
code: sourceCodePro.style.fontFamily,
},
components: {
JoyButton: {
styleOverrides: {
root: ({ ownerState }) => ({
...(ownerState.color === 'primary' && {
backgroundColor: '#4338ca',
}),
}),
},
},
},
});
export default theme;

View File

@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}