first commit
This commit is contained in:
35
.gitignore
vendored
Normal file
35
.gitignore
vendored
Normal 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
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Next UI
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
53
README.md
Normal file
53
README.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Next.js & HeroUI Template
|
||||
|
||||
This is a template for creating applications using Next.js 14 (app directory) and HeroUI (v2).
|
||||
|
||||
[Try it on CodeSandbox](https://githubbox.com/heroui-inc/heroui/next-app-template)
|
||||
|
||||
## Technologies Used
|
||||
|
||||
- [Next.js 14](https://nextjs.org/docs/getting-started)
|
||||
- [HeroUI v2](https://heroui.com/)
|
||||
- [Tailwind CSS](https://tailwindcss.com/)
|
||||
- [Tailwind Variants](https://tailwind-variants.org)
|
||||
- [TypeScript](https://www.typescriptlang.org/)
|
||||
- [Framer Motion](https://www.framer.com/motion/)
|
||||
- [next-themes](https://github.com/pacocoursey/next-themes)
|
||||
|
||||
## How to Use
|
||||
|
||||
### Use the template with create-next-app
|
||||
|
||||
To create a new project based on this template using `create-next-app`, run the following command:
|
||||
|
||||
```bash
|
||||
npx create-next-app -e https://github.com/heroui-inc/next-app-template
|
||||
```
|
||||
|
||||
### Install dependencies
|
||||
|
||||
You can use one of them `npm`, `yarn`, `pnpm`, `bun`, Example using `npm`:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### Run the development server
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Setup pnpm (optional)
|
||||
|
||||
If you are using `pnpm`, you need to add the following code to your `.npmrc` file:
|
||||
|
||||
```bash
|
||||
public-hoist-pattern[]=*@heroui/*
|
||||
```
|
||||
|
||||
After modifying the `.npmrc` file, you need to run `pnpm install` again to ensure that the dependencies are installed correctly.
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the [MIT license](https://github.com/heroui-inc/next-app-template/blob/main/LICENSE).
|
||||
13
app/about/layout.tsx
Normal file
13
app/about/layout.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
export default function AboutLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
|
||||
<div className="inline-block max-w-lg text-center justify-center">
|
||||
{children}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
9
app/about/page.tsx
Normal file
9
app/about/page.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { title } from "@/components/primitives";
|
||||
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className={title()}>About</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
13
app/blog/layout.tsx
Normal file
13
app/blog/layout.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
export default function BlogLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
|
||||
<div className="inline-block max-w-lg text-center justify-center">
|
||||
{children}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
9
app/blog/page.tsx
Normal file
9
app/blog/page.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { title } from "@/components/primitives";
|
||||
|
||||
export default function BlogPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className={title()}>Blog</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
13
app/docs/layout.tsx
Normal file
13
app/docs/layout.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
export default function DocsLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
|
||||
<div className="inline-block max-w-lg text-center justify-center">
|
||||
{children}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
9
app/docs/page.tsx
Normal file
9
app/docs/page.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { title } from "@/components/primitives";
|
||||
|
||||
export default function DocsPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className={title()}>Docs</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
31
app/error.tsx
Normal file
31
app/error.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function Error({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error;
|
||||
reset: () => void;
|
||||
}) {
|
||||
useEffect(() => {
|
||||
// Log the error to an error reporting service
|
||||
/* eslint-disable no-console */
|
||||
console.error(error);
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Something went wrong!</h2>
|
||||
<button
|
||||
onClick={
|
||||
// Attempt to recover by trying to re-render the segment
|
||||
() => reset()
|
||||
}
|
||||
>
|
||||
Try again
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
66
app/layout.tsx
Normal file
66
app/layout.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import "@/styles/globals.css";
|
||||
import { Metadata, Viewport } from "next";
|
||||
import { Link } from "@heroui/link";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { Providers } from "./providers";
|
||||
|
||||
import { siteConfig } from "@/config/site";
|
||||
import { fontSans } from "@/config/fonts";
|
||||
import { Navbar } from "@/components/navbar";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: siteConfig.name,
|
||||
template: `%s - ${siteConfig.name}`,
|
||||
},
|
||||
description: siteConfig.description,
|
||||
icons: {
|
||||
icon: "/favicon.ico",
|
||||
},
|
||||
};
|
||||
|
||||
export const viewport: Viewport = {
|
||||
themeColor: [
|
||||
{ media: "(prefers-color-scheme: light)", color: "white" },
|
||||
{ media: "(prefers-color-scheme: dark)", color: "black" },
|
||||
],
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html suppressHydrationWarning lang="en">
|
||||
<head />
|
||||
<body
|
||||
className={clsx(
|
||||
"min-h-screen text-foreground bg-background font-sans antialiased",
|
||||
fontSans.variable,
|
||||
)}
|
||||
>
|
||||
<Providers themeProps={{ attribute: "class", defaultTheme: "dark" }}>
|
||||
<div className="relative flex flex-col h-screen">
|
||||
<Navbar />
|
||||
<main className="container mx-auto max-w-7xl pt-16 px-6 flex-grow">
|
||||
{children}
|
||||
</main>
|
||||
<footer className="w-full flex items-center justify-center py-3">
|
||||
<Link
|
||||
isExternal
|
||||
className="flex items-center gap-1 text-current"
|
||||
href="https://heroui.com?utm_source=next-app-template"
|
||||
title="heroui.com homepage"
|
||||
>
|
||||
<span className="text-default-600">Powered by</span>
|
||||
<p className="text-primary">HeroUI</p>
|
||||
</Link>
|
||||
</footer>
|
||||
</div>
|
||||
</Providers>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
56
app/page.tsx
Normal file
56
app/page.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Link } from "@heroui/link";
|
||||
import { Snippet } from "@heroui/snippet";
|
||||
import { Code } from "@heroui/code";
|
||||
import { button as buttonStyles } from "@heroui/theme";
|
||||
|
||||
import { siteConfig } from "@/config/site";
|
||||
import { title, subtitle } from "@/components/primitives";
|
||||
import { GithubIcon } from "@/components/icons";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
|
||||
<div className="inline-block max-w-xl text-center justify-center">
|
||||
<span className={title()}>Make </span>
|
||||
<span className={title({ color: "violet" })}>beautiful </span>
|
||||
<br />
|
||||
<span className={title()}>
|
||||
websites regardless of your design experience.
|
||||
</span>
|
||||
<div className={subtitle({ class: "mt-4" })}>
|
||||
Beautiful, fast and modern React UI library.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<Link
|
||||
isExternal
|
||||
className={buttonStyles({
|
||||
color: "primary",
|
||||
radius: "full",
|
||||
variant: "shadow",
|
||||
})}
|
||||
href={siteConfig.links.docs}
|
||||
>
|
||||
Documentation
|
||||
</Link>
|
||||
<Link
|
||||
isExternal
|
||||
className={buttonStyles({ variant: "bordered", radius: "full" })}
|
||||
href={siteConfig.links.github}
|
||||
>
|
||||
<GithubIcon size={20} />
|
||||
GitHub
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<Snippet hideCopyButton hideSymbol variant="bordered">
|
||||
<span>
|
||||
Get started by editing <Code color="primary">app/page.tsx</Code>
|
||||
</span>
|
||||
</Snippet>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
13
app/pricing/layout.tsx
Normal file
13
app/pricing/layout.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
export default function PricingLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
|
||||
<div className="inline-block max-w-lg text-center justify-center">
|
||||
{children}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
9
app/pricing/page.tsx
Normal file
9
app/pricing/page.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { title } from "@/components/primitives";
|
||||
|
||||
export default function PricingPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className={title()}>Pricing</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
31
app/providers.tsx
Normal file
31
app/providers.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
"use client";
|
||||
|
||||
import type { ThemeProviderProps } from "next-themes";
|
||||
|
||||
import * as React from "react";
|
||||
import { HeroUIProvider } from "@heroui/system";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||
|
||||
export interface ProvidersProps {
|
||||
children: React.ReactNode;
|
||||
themeProps?: ThemeProviderProps;
|
||||
}
|
||||
|
||||
declare module "@react-types/shared" {
|
||||
interface RouterConfig {
|
||||
routerOptions: NonNullable<
|
||||
Parameters<ReturnType<typeof useRouter>["push"]>[1]
|
||||
>;
|
||||
}
|
||||
}
|
||||
|
||||
export function Providers({ children, themeProps }: ProvidersProps) {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<HeroUIProvider navigate={router.push}>
|
||||
<NextThemesProvider {...themeProps}>{children}</NextThemesProvider>
|
||||
</HeroUIProvider>
|
||||
);
|
||||
}
|
||||
14
components/counter.tsx
Normal file
14
components/counter.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Button } from "@heroui/button";
|
||||
|
||||
export const Counter = () => {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
return (
|
||||
<Button radius="full" onPress={() => setCount(count + 1)}>
|
||||
Count is {count}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
187
components/icons.tsx
Normal file
187
components/icons.tsx
Normal file
@@ -0,0 +1,187 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { IconSvgProps } from "@/types";
|
||||
|
||||
export const Logo: React.FC<IconSvgProps> = ({
|
||||
size = 36,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}) => (
|
||||
<svg
|
||||
fill="none"
|
||||
height={size || height}
|
||||
viewBox="0 0 32 32"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
clipRule="evenodd"
|
||||
d="M17.6482 10.1305L15.8785 7.02583L7.02979 22.5499H10.5278L17.6482 10.1305ZM19.8798 14.0457L18.11 17.1983L19.394 19.4511H16.8453L15.1056 22.5499H24.7272L19.8798 14.0457Z"
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const DiscordIcon: React.FC<IconSvgProps> = ({
|
||||
size = 24,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
height={size || height}
|
||||
viewBox="0 0 24 24"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M14.82 4.26a10.14 10.14 0 0 0-.53 1.1 14.66 14.66 0 0 0-4.58 0 10.14 10.14 0 0 0-.53-1.1 16 16 0 0 0-4.13 1.3 17.33 17.33 0 0 0-3 11.59 16.6 16.6 0 0 0 5.07 2.59A12.89 12.89 0 0 0 8.23 18a9.65 9.65 0 0 1-1.71-.83 3.39 3.39 0 0 0 .42-.33 11.66 11.66 0 0 0 10.12 0q.21.18.42.33a10.84 10.84 0 0 1-1.71.84 12.41 12.41 0 0 0 1.08 1.78 16.44 16.44 0 0 0 5.06-2.59 17.22 17.22 0 0 0-3-11.59 16.09 16.09 0 0 0-4.09-1.35zM8.68 14.81a1.94 1.94 0 0 1-1.8-2 1.93 1.93 0 0 1 1.8-2 1.93 1.93 0 0 1 1.8 2 1.93 1.93 0 0 1-1.8 2zm6.64 0a1.94 1.94 0 0 1-1.8-2 1.93 1.93 0 0 1 1.8-2 1.92 1.92 0 0 1 1.8 2 1.92 1.92 0 0 1-1.8 2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const TwitterIcon: React.FC<IconSvgProps> = ({
|
||||
size = 24,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
height={size || height}
|
||||
viewBox="0 0 24 24"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M19.633 7.997c.013.175.013.349.013.523 0 5.325-4.053 11.461-11.46 11.461-2.282 0-4.402-.661-6.186-1.809.324.037.636.05.973.05a8.07 8.07 0 0 0 5.001-1.721 4.036 4.036 0 0 1-3.767-2.793c.249.037.499.062.761.062.361 0 .724-.05 1.061-.137a4.027 4.027 0 0 1-3.23-3.953v-.05c.537.299 1.16.486 1.82.511a4.022 4.022 0 0 1-1.796-3.354c0-.748.199-1.434.548-2.032a11.457 11.457 0 0 0 8.306 4.215c-.062-.3-.1-.611-.1-.923a4.026 4.026 0 0 1 4.028-4.028c1.16 0 2.207.486 2.943 1.272a7.957 7.957 0 0 0 2.556-.973 4.02 4.02 0 0 1-1.771 2.22 8.073 8.073 0 0 0 2.319-.624 8.645 8.645 0 0 1-2.019 2.083z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const GithubIcon: React.FC<IconSvgProps> = ({
|
||||
size = 24,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
height={size || height}
|
||||
viewBox="0 0 24 24"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
clipRule="evenodd"
|
||||
d="M12.026 2c-5.509 0-9.974 4.465-9.974 9.974 0 4.406 2.857 8.145 6.821 9.465.499.09.679-.217.679-.481 0-.237-.008-.865-.011-1.696-2.775.602-3.361-1.338-3.361-1.338-.452-1.152-1.107-1.459-1.107-1.459-.905-.619.069-.605.069-.605 1.002.07 1.527 1.028 1.527 1.028.89 1.524 2.336 1.084 2.902.829.091-.645.351-1.085.635-1.334-2.214-.251-4.542-1.107-4.542-4.93 0-1.087.389-1.979 1.024-2.675-.101-.253-.446-1.268.099-2.64 0 0 .837-.269 2.742 1.021a9.582 9.582 0 0 1 2.496-.336 9.554 9.554 0 0 1 2.496.336c1.906-1.291 2.742-1.021 2.742-1.021.545 1.372.203 2.387.099 2.64.64.696 1.024 1.587 1.024 2.675 0 3.833-2.33 4.675-4.552 4.922.355.308.675.916.675 1.846 0 1.334-.012 2.41-.012 2.737 0 .267.178.577.687.479C19.146 20.115 22 16.379 22 11.974 22 6.465 17.535 2 12.026 2z"
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const MoonFilledIcon = ({
|
||||
size = 24,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}: IconSvgProps) => (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
height={size || height}
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M21.53 15.93c-.16-.27-.61-.69-1.73-.49a8.46 8.46 0 01-1.88.13 8.409 8.409 0 01-5.91-2.82 8.068 8.068 0 01-1.44-8.66c.44-1.01.13-1.54-.09-1.76s-.77-.55-1.83-.11a10.318 10.318 0 00-6.32 10.21 10.475 10.475 0 007.04 8.99 10 10 0 002.89.55c.16.01.32.02.48.02a10.5 10.5 0 008.47-4.27c.67-.93.49-1.519.32-1.79z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const SunFilledIcon = ({
|
||||
size = 24,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}: IconSvgProps) => (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
height={size || height}
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<g fill="currentColor">
|
||||
<path d="M19 12a7 7 0 11-7-7 7 7 0 017 7z" />
|
||||
<path d="M12 22.96a.969.969 0 01-1-.96v-.08a1 1 0 012 0 1.038 1.038 0 01-1 1.04zm7.14-2.82a1.024 1.024 0 01-.71-.29l-.13-.13a1 1 0 011.41-1.41l.13.13a1 1 0 010 1.41.984.984 0 01-.7.29zm-14.28 0a1.024 1.024 0 01-.71-.29 1 1 0 010-1.41l.13-.13a1 1 0 011.41 1.41l-.13.13a1 1 0 01-.7.29zM22 13h-.08a1 1 0 010-2 1.038 1.038 0 011.04 1 .969.969 0 01-.96 1zM2.08 13H2a1 1 0 010-2 1.038 1.038 0 011.04 1 .969.969 0 01-.96 1zm16.93-7.01a1.024 1.024 0 01-.71-.29 1 1 0 010-1.41l.13-.13a1 1 0 011.41 1.41l-.13.13a.984.984 0 01-.7.29zm-14.02 0a1.024 1.024 0 01-.71-.29l-.13-.14a1 1 0 011.41-1.41l.13.13a1 1 0 010 1.41.97.97 0 01-.7.3zM12 3.04a.969.969 0 01-1-.96V2a1 1 0 012 0 1.038 1.038 0 01-1 1.04z" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const HeartFilledIcon = ({
|
||||
size = 24,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}: IconSvgProps) => (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
height={size || height}
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M12.62 20.81c-.34.12-.9.12-1.24 0C8.48 19.82 2 15.69 2 8.69 2 5.6 4.49 3.1 7.56 3.1c1.82 0 3.43.88 4.44 2.24a5.53 5.53 0 0 1 4.44-2.24C19.51 3.1 22 5.6 22 8.69c0 7-6.48 11.13-9.38 12.12Z"
|
||||
fill="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const SearchIcon = (props: IconSvgProps) => (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M11.5 21C16.7467 21 21 16.7467 21 11.5C21 6.25329 16.7467 2 11.5 2C6.25329 2 2 6.25329 2 11.5C2 16.7467 6.25329 21 11.5 21Z"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<path
|
||||
d="M22 22L20 20"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
141
components/navbar.tsx
Normal file
141
components/navbar.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
import {
|
||||
Navbar as HeroUINavbar,
|
||||
NavbarContent,
|
||||
NavbarMenu,
|
||||
NavbarMenuToggle,
|
||||
NavbarBrand,
|
||||
NavbarItem,
|
||||
NavbarMenuItem,
|
||||
} from "@heroui/navbar";
|
||||
import { Button } from "@heroui/button";
|
||||
import { Kbd } from "@heroui/kbd";
|
||||
import { Link } from "@heroui/link";
|
||||
import { Input } from "@heroui/input";
|
||||
import { link as linkStyles } from "@heroui/theme";
|
||||
import NextLink from "next/link";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { siteConfig } from "@/config/site";
|
||||
import { ThemeSwitch } from "@/components/theme-switch";
|
||||
import {
|
||||
TwitterIcon,
|
||||
GithubIcon,
|
||||
DiscordIcon,
|
||||
HeartFilledIcon,
|
||||
SearchIcon,
|
||||
Logo,
|
||||
} from "@/components/icons";
|
||||
|
||||
export const Navbar = () => {
|
||||
const searchInput = (
|
||||
<Input
|
||||
aria-label="Search"
|
||||
classNames={{
|
||||
inputWrapper: "bg-default-100",
|
||||
input: "text-sm",
|
||||
}}
|
||||
endContent={
|
||||
<Kbd className="hidden lg:inline-block" keys={["command"]}>
|
||||
K
|
||||
</Kbd>
|
||||
}
|
||||
labelPlacement="outside"
|
||||
placeholder="Search..."
|
||||
startContent={
|
||||
<SearchIcon className="text-base text-default-400 pointer-events-none flex-shrink-0" />
|
||||
}
|
||||
type="search"
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<HeroUINavbar maxWidth="xl" position="sticky">
|
||||
<NavbarContent className="basis-1/5 sm:basis-full" justify="start">
|
||||
<NavbarBrand as="li" className="gap-3 max-w-fit">
|
||||
<NextLink className="flex justify-start items-center gap-1" href="/">
|
||||
<Logo />
|
||||
<p className="font-bold text-inherit">ACME</p>
|
||||
</NextLink>
|
||||
</NavbarBrand>
|
||||
<ul className="hidden lg:flex gap-4 justify-start ml-2">
|
||||
{siteConfig.navItems.map((item) => (
|
||||
<NavbarItem key={item.href}>
|
||||
<NextLink
|
||||
className={clsx(
|
||||
linkStyles({ color: "foreground" }),
|
||||
"data-[active=true]:text-primary data-[active=true]:font-medium",
|
||||
)}
|
||||
color="foreground"
|
||||
href={item.href}
|
||||
>
|
||||
{item.label}
|
||||
</NextLink>
|
||||
</NavbarItem>
|
||||
))}
|
||||
</ul>
|
||||
</NavbarContent>
|
||||
|
||||
<NavbarContent
|
||||
className="hidden sm:flex basis-1/5 sm:basis-full"
|
||||
justify="end"
|
||||
>
|
||||
<NavbarItem className="hidden sm:flex gap-2">
|
||||
<Link isExternal aria-label="Twitter" href={siteConfig.links.twitter}>
|
||||
<TwitterIcon className="text-default-500" />
|
||||
</Link>
|
||||
<Link isExternal aria-label="Discord" href={siteConfig.links.discord}>
|
||||
<DiscordIcon className="text-default-500" />
|
||||
</Link>
|
||||
<Link isExternal aria-label="Github" href={siteConfig.links.github}>
|
||||
<GithubIcon className="text-default-500" />
|
||||
</Link>
|
||||
<ThemeSwitch />
|
||||
</NavbarItem>
|
||||
<NavbarItem className="hidden lg:flex">{searchInput}</NavbarItem>
|
||||
<NavbarItem className="hidden md:flex">
|
||||
<Button
|
||||
isExternal
|
||||
as={Link}
|
||||
className="text-sm font-normal text-default-600 bg-default-100"
|
||||
href={siteConfig.links.sponsor}
|
||||
startContent={<HeartFilledIcon className="text-danger" />}
|
||||
variant="flat"
|
||||
>
|
||||
Sponsor
|
||||
</Button>
|
||||
</NavbarItem>
|
||||
</NavbarContent>
|
||||
|
||||
<NavbarContent className="sm:hidden basis-1 pl-4" justify="end">
|
||||
<Link isExternal aria-label="Github" href={siteConfig.links.github}>
|
||||
<GithubIcon className="text-default-500" />
|
||||
</Link>
|
||||
<ThemeSwitch />
|
||||
<NavbarMenuToggle />
|
||||
</NavbarContent>
|
||||
|
||||
<NavbarMenu>
|
||||
{searchInput}
|
||||
<div className="mx-4 mt-2 flex flex-col gap-2">
|
||||
{siteConfig.navMenuItems.map((item, index) => (
|
||||
<NavbarMenuItem key={`${item}-${index}`}>
|
||||
<Link
|
||||
color={
|
||||
index === 2
|
||||
? "primary"
|
||||
: index === siteConfig.navMenuItems.length - 1
|
||||
? "danger"
|
||||
: "foreground"
|
||||
}
|
||||
href="#"
|
||||
size="lg"
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
</NavbarMenuItem>
|
||||
))}
|
||||
</div>
|
||||
</NavbarMenu>
|
||||
</HeroUINavbar>
|
||||
);
|
||||
};
|
||||
53
components/primitives.ts
Normal file
53
components/primitives.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { tv } from "tailwind-variants";
|
||||
|
||||
export const title = tv({
|
||||
base: "tracking-tight inline font-semibold",
|
||||
variants: {
|
||||
color: {
|
||||
violet: "from-[#FF1CF7] to-[#b249f8]",
|
||||
yellow: "from-[#FF705B] to-[#FFB457]",
|
||||
blue: "from-[#5EA2EF] to-[#0072F5]",
|
||||
cyan: "from-[#00b7fa] to-[#01cfea]",
|
||||
green: "from-[#6FEE8D] to-[#17c964]",
|
||||
pink: "from-[#FF72E1] to-[#F54C7A]",
|
||||
foreground: "dark:from-[#FFFFFF] dark:to-[#4B4B4B]",
|
||||
},
|
||||
size: {
|
||||
sm: "text-3xl lg:text-4xl",
|
||||
md: "text-[2.3rem] lg:text-5xl leading-9",
|
||||
lg: "text-4xl lg:text-6xl",
|
||||
},
|
||||
fullWidth: {
|
||||
true: "w-full block",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: "md",
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
color: [
|
||||
"violet",
|
||||
"yellow",
|
||||
"blue",
|
||||
"cyan",
|
||||
"green",
|
||||
"pink",
|
||||
"foreground",
|
||||
],
|
||||
class: "bg-clip-text text-transparent bg-gradient-to-b",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const subtitle = tv({
|
||||
base: "w-full md:w-1/2 my-2 text-lg lg:text-xl text-default-600 block max-w-full",
|
||||
variants: {
|
||||
fullWidth: {
|
||||
true: "!w-full",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
fullWidth: true,
|
||||
},
|
||||
});
|
||||
81
components/theme-switch.tsx
Normal file
81
components/theme-switch.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
"use client";
|
||||
|
||||
import { FC } from "react";
|
||||
import { VisuallyHidden } from "@react-aria/visually-hidden";
|
||||
import { SwitchProps, useSwitch } from "@heroui/switch";
|
||||
import { useTheme } from "next-themes";
|
||||
import { useIsSSR } from "@react-aria/ssr";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { SunFilledIcon, MoonFilledIcon } from "@/components/icons";
|
||||
|
||||
export interface ThemeSwitchProps {
|
||||
className?: string;
|
||||
classNames?: SwitchProps["classNames"];
|
||||
}
|
||||
|
||||
export const ThemeSwitch: FC<ThemeSwitchProps> = ({
|
||||
className,
|
||||
classNames,
|
||||
}) => {
|
||||
const { theme, setTheme } = useTheme();
|
||||
const isSSR = useIsSSR();
|
||||
|
||||
const onChange = () => {
|
||||
theme === "light" ? setTheme("dark") : setTheme("light");
|
||||
};
|
||||
|
||||
const {
|
||||
Component,
|
||||
slots,
|
||||
isSelected,
|
||||
getBaseProps,
|
||||
getInputProps,
|
||||
getWrapperProps,
|
||||
} = useSwitch({
|
||||
isSelected: theme === "light" || isSSR,
|
||||
"aria-label": `Switch to ${theme === "light" || isSSR ? "dark" : "light"} mode`,
|
||||
onChange,
|
||||
});
|
||||
|
||||
return (
|
||||
<Component
|
||||
{...getBaseProps({
|
||||
className: clsx(
|
||||
"px-px transition-opacity hover:opacity-80 cursor-pointer",
|
||||
className,
|
||||
classNames?.base,
|
||||
),
|
||||
})}
|
||||
>
|
||||
<VisuallyHidden>
|
||||
<input {...getInputProps()} />
|
||||
</VisuallyHidden>
|
||||
<div
|
||||
{...getWrapperProps()}
|
||||
className={slots.wrapper({
|
||||
class: clsx(
|
||||
[
|
||||
"w-auto h-auto",
|
||||
"bg-transparent",
|
||||
"rounded-lg",
|
||||
"flex items-center justify-center",
|
||||
"group-data-[selected=true]:bg-transparent",
|
||||
"!text-default-500",
|
||||
"pt-px",
|
||||
"px-0",
|
||||
"mx-0",
|
||||
],
|
||||
classNames?.wrapper,
|
||||
),
|
||||
})}
|
||||
>
|
||||
{!isSelected || isSSR ? (
|
||||
<SunFilledIcon size={22} />
|
||||
) : (
|
||||
<MoonFilledIcon size={22} />
|
||||
)}
|
||||
</div>
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
11
config/fonts.ts
Normal file
11
config/fonts.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Fira_Code as FontMono, Inter as FontSans } from "next/font/google";
|
||||
|
||||
export const fontSans = FontSans({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-sans",
|
||||
});
|
||||
|
||||
export const fontMono = FontMono({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-mono",
|
||||
});
|
||||
69
config/site.ts
Normal file
69
config/site.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
export type SiteConfig = typeof siteConfig;
|
||||
|
||||
export const siteConfig = {
|
||||
name: "Next.js + HeroUI",
|
||||
description: "Make beautiful websites regardless of your design experience.",
|
||||
navItems: [
|
||||
{
|
||||
label: "Home",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
label: "Docs",
|
||||
href: "/docs",
|
||||
},
|
||||
{
|
||||
label: "Pricing",
|
||||
href: "/pricing",
|
||||
},
|
||||
{
|
||||
label: "Blog",
|
||||
href: "/blog",
|
||||
},
|
||||
{
|
||||
label: "About",
|
||||
href: "/about",
|
||||
},
|
||||
],
|
||||
navMenuItems: [
|
||||
{
|
||||
label: "Profile",
|
||||
href: "/profile",
|
||||
},
|
||||
{
|
||||
label: "Dashboard",
|
||||
href: "/dashboard",
|
||||
},
|
||||
{
|
||||
label: "Projects",
|
||||
href: "/projects",
|
||||
},
|
||||
{
|
||||
label: "Team",
|
||||
href: "/team",
|
||||
},
|
||||
{
|
||||
label: "Calendar",
|
||||
href: "/calendar",
|
||||
},
|
||||
{
|
||||
label: "Settings",
|
||||
href: "/settings",
|
||||
},
|
||||
{
|
||||
label: "Help & Feedback",
|
||||
href: "/help-feedback",
|
||||
},
|
||||
{
|
||||
label: "Logout",
|
||||
href: "/logout",
|
||||
},
|
||||
],
|
||||
links: {
|
||||
github: "https://github.com/heroui-inc/heroui",
|
||||
twitter: "https://twitter.com/hero_ui",
|
||||
docs: "https://heroui.com",
|
||||
discord: "https://discord.gg/9b6yyZKmH4",
|
||||
sponsor: "https://patreon.com/jrgarciadev",
|
||||
},
|
||||
};
|
||||
151
eslint.config.mjs
Normal file
151
eslint.config.mjs
Normal file
@@ -0,0 +1,151 @@
|
||||
import { defineConfig, globalIgnores } from "eslint/config";
|
||||
import { fixupConfigRules, fixupPluginRules } from "@eslint/compat";
|
||||
import react from "eslint-plugin-react";
|
||||
import unusedImports from "eslint-plugin-unused-imports";
|
||||
import _import from "eslint-plugin-import";
|
||||
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
||||
import jsxA11Y from "eslint-plugin-jsx-a11y";
|
||||
import prettier from "eslint-plugin-prettier";
|
||||
import globals from "globals";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import js from "@eslint/js";
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all
|
||||
});
|
||||
|
||||
export default defineConfig([globalIgnores([
|
||||
".now/*",
|
||||
"**/*.css",
|
||||
"**/.changeset",
|
||||
"**/dist",
|
||||
"esm/*",
|
||||
"public/*",
|
||||
"tests/*",
|
||||
"scripts/*",
|
||||
"**/*.config.js",
|
||||
"**/.DS_Store",
|
||||
"**/node_modules",
|
||||
"**/coverage",
|
||||
"**/.next",
|
||||
"**/build",
|
||||
"!**/.commitlintrc.cjs",
|
||||
"!**/.lintstagedrc.cjs",
|
||||
"!**/jest.config.js",
|
||||
"!**/plopfile.js",
|
||||
"!**/react-shim.js",
|
||||
"!**/tsup.config.ts",
|
||||
]), {
|
||||
extends: fixupConfigRules(compat.extends(
|
||||
"plugin:react/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:react-hooks/recommended",
|
||||
"plugin:jsx-a11y/recommended",
|
||||
"plugin:@next/next/recommended",
|
||||
)),
|
||||
|
||||
plugins: {
|
||||
react: fixupPluginRules(react),
|
||||
"unused-imports": unusedImports,
|
||||
import: fixupPluginRules(_import),
|
||||
"@typescript-eslint": typescriptEslint,
|
||||
"jsx-a11y": fixupPluginRules(jsxA11Y),
|
||||
prettier: fixupPluginRules(prettier),
|
||||
},
|
||||
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...Object.fromEntries(Object.entries(globals.browser).map(([key]) => [key, "off"])),
|
||||
...globals.node,
|
||||
},
|
||||
|
||||
parser: tsParser,
|
||||
ecmaVersion: 12,
|
||||
sourceType: "module",
|
||||
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
},
|
||||
},
|
||||
|
||||
files: ["**/*.ts", "**/*.tsx"],
|
||||
|
||||
rules: {
|
||||
"no-console": "warn",
|
||||
"react/prop-types": "off",
|
||||
"react/jsx-uses-react": "off",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react-hooks/exhaustive-deps": "off",
|
||||
"jsx-a11y/click-events-have-key-events": "warn",
|
||||
"jsx-a11y/interactive-supports-focus": "warn",
|
||||
"prettier/prettier": "warn",
|
||||
"no-unused-vars": "off",
|
||||
"unused-imports/no-unused-vars": "off",
|
||||
"unused-imports/no-unused-imports": "warn",
|
||||
|
||||
"@typescript-eslint/no-unused-vars": ["warn", {
|
||||
args: "after-used",
|
||||
ignoreRestSiblings: false,
|
||||
argsIgnorePattern: "^_.*?$",
|
||||
}],
|
||||
|
||||
"import/order": ["warn", {
|
||||
groups: [
|
||||
"type",
|
||||
"builtin",
|
||||
"object",
|
||||
"external",
|
||||
"internal",
|
||||
"parent",
|
||||
"sibling",
|
||||
"index",
|
||||
],
|
||||
|
||||
pathGroups: [{
|
||||
pattern: "~/**",
|
||||
group: "external",
|
||||
position: "after",
|
||||
}],
|
||||
|
||||
"newlines-between": "always",
|
||||
}],
|
||||
|
||||
"react/self-closing-comp": "warn",
|
||||
|
||||
"react/jsx-sort-props": ["warn", {
|
||||
callbacksLast: true,
|
||||
shorthandFirst: true,
|
||||
noSortAlphabetically: false,
|
||||
reservedFirst: true,
|
||||
}],
|
||||
|
||||
"padding-line-between-statements": ["warn", {
|
||||
blankLine: "always",
|
||||
prev: "*",
|
||||
next: "return",
|
||||
}, {
|
||||
blankLine: "always",
|
||||
prev: ["const", "let", "var"],
|
||||
next: "*",
|
||||
}, {
|
||||
blankLine: "any",
|
||||
prev: ["const", "let", "var"],
|
||||
next: ["const", "let", "var"],
|
||||
}],
|
||||
},
|
||||
}]);
|
||||
4
next.config.js
Normal file
4
next.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
|
||||
module.exports = nextConfig;
|
||||
62
package.json
Normal file
62
package.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "next-app-template",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@heroui/button": "2.2.22",
|
||||
"@heroui/code": "2.2.16",
|
||||
"@heroui/input": "2.4.22",
|
||||
"@heroui/kbd": "2.2.17",
|
||||
"@heroui/link": "2.2.19",
|
||||
"@heroui/listbox": "2.3.21",
|
||||
"@heroui/navbar": "2.2.20",
|
||||
"@heroui/snippet": "2.2.23",
|
||||
"@heroui/switch": "2.2.20",
|
||||
"@heroui/system": "2.4.18",
|
||||
"@heroui/theme": "2.4.17",
|
||||
"@react-aria/ssr": "3.9.9",
|
||||
"@react-aria/visually-hidden": "3.8.24",
|
||||
"clsx": "2.1.1",
|
||||
"framer-motion": "11.13.1",
|
||||
"intl-messageformat": "10.7.16",
|
||||
"next": "15.3.1",
|
||||
"next-themes": "0.4.6",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "1.2.8",
|
||||
"@eslint/eslintrc": "3.3.1",
|
||||
"@eslint/js": "9.25.1",
|
||||
"@next/eslint-plugin-next": "15.3.1",
|
||||
"@react-types/shared": "3.30.0",
|
||||
"@types/node": "22.15.3",
|
||||
"@types/react": "18.3.3",
|
||||
"@types/react-dom": "18.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.31.1",
|
||||
"@typescript-eslint/parser": "8.31.1",
|
||||
"autoprefixer": "10.4.21",
|
||||
"eslint": "9.25.1",
|
||||
"eslint-config-next": "15.3.1",
|
||||
"eslint-config-prettier": "10.1.2",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-jsx-a11y": "6.10.2",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-prettier": "5.2.6",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react-hooks": "5.2.0",
|
||||
"eslint-plugin-unused-imports": "4.1.4",
|
||||
"globals": "16.0.0",
|
||||
"postcss": "8.5.3",
|
||||
"prettier": "3.5.3",
|
||||
"tailwind-variants": "0.3.0",
|
||||
"tailwindcss": "3.4.16",
|
||||
"typescript": "5.6.3"
|
||||
}
|
||||
}
|
||||
5478
pnpm-lock.yaml
generated
Normal file
5478
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
4
pnpm-workspace.yaml
Normal file
4
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
onlyBuiltDependencies:
|
||||
- '@heroui/shared-utils'
|
||||
- sharp
|
||||
- unrs-resolver
|
||||
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
1
public/next.svg
Normal file
1
public/next.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
public/vercel.svg
Normal file
1
public/vercel.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
||||
|
After Width: | Height: | Size: 629 B |
3
styles/globals.css
Normal file
3
styles/globals.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
22
tailwind.config.js
Normal file
22
tailwind.config.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import {heroui} from "@heroui/theme"
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
const config = {
|
||||
content: [
|
||||
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
"./node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}"
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ["var(--font-sans)"],
|
||||
mono: ["var(--font-mono)"],
|
||||
},
|
||||
},
|
||||
},
|
||||
darkMode: "class",
|
||||
plugins: [heroui()],
|
||||
}
|
||||
|
||||
module.exports = config;
|
||||
28
tsconfig.json
Normal file
28
tsconfig.json
Normal 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": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
5
types/index.ts
Normal file
5
types/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { SVGProps } from "react";
|
||||
|
||||
export type IconSvgProps = SVGProps<SVGSVGElement> & {
|
||||
size?: number;
|
||||
};
|
||||
Reference in New Issue
Block a user