From 338a3f21109420874cdf29f350b315ba9d5e2b09 Mon Sep 17 00:00:00 2001 From: SevicheCC <91365763+Sevichecc@users.noreply.github.com> Date: Sun, 4 Jun 2023 15:28:03 +0800 Subject: [PATCH] feat: add shadcn ui and forms --- .env.developement | 1 - .eslintrc.json | 2 +- README.md | 34 - app/globals.css | 0 app/layout.tsx | 6 +- app/page.tsx | 6 +- app/register.tsx | 22 - components/InputForm.tsx | 65 + components/ui/button.tsx | 55 + components/ui/form.tsx | 176 + components/ui/input.tsx | 25 + components/ui/label.tsx | 26 + lib/utils.ts | 7 + next.config.js | 24 +- package-lock.json | 4613 +++++++++++++++++++++ package.json | 28 +- pnpm-lock.yaml | 8150 +++----------------------------------- postcss.config.js | 6 + styles/globals.css | 81 + tailwind.config.ts | 73 + tamagui.config.ts | 14 - tsconfig.json | 9 +- 22 files changed, 5665 insertions(+), 7758 deletions(-) delete mode 100644 .env.developement delete mode 100644 app/globals.css delete mode 100644 app/register.tsx create mode 100644 components/InputForm.tsx create mode 100644 components/ui/button.tsx create mode 100644 components/ui/form.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/label.tsx create mode 100644 lib/utils.ts create mode 100644 package-lock.json create mode 100644 postcss.config.js create mode 100644 styles/globals.css create mode 100644 tailwind.config.ts delete mode 100644 tamagui.config.ts diff --git a/.env.developement b/.env.developement deleted file mode 100644 index 3664bc9..0000000 --- a/.env.developement +++ /dev/null @@ -1 +0,0 @@ -TAMAGUI_TARGET=web \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 528301f..4d765f2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": ["next/core-web-vitals", "@antfu", "prettier"] + "extends": ["next/core-web-vitals", "prettier"] } diff --git a/README.md b/README.md index f4da3c4..e69de29 100644 --- a/README.md +++ b/README.md @@ -1,34 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/app/globals.css b/app/globals.css deleted file mode 100644 index e69de29..0000000 diff --git a/app/layout.tsx b/app/layout.tsx index 8461fad..d9f46e0 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,7 +1,5 @@ -import './globals.css' +import "@/styles/globals.css" import { Inter } from 'next/font/google' -import { NextTamaguiProvider } from './register' - const inter = Inter({ subsets: ['latin'] }) export const metadata = { @@ -17,7 +15,7 @@ export default function RootLayout({ return ( - {children} + {children} ) diff --git a/app/page.tsx b/app/page.tsx index 405e6f1..a79f27d 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,7 +1,9 @@ +import InputForm from "@/components/InputForm" + export default function Home() { return ( -
- +
+
) } diff --git a/app/register.tsx b/app/register.tsx deleted file mode 100644 index 9cd9dac..0000000 --- a/app/register.tsx +++ /dev/null @@ -1,22 +0,0 @@ -'use client' -import { useServerInsertedHTML } from 'next/navigation'; -import { TamaguiProvider } from 'tamagui' -import config from '../tamagui.config' -import '@tamagui/core/reset.css' - -if (process.env.NODE_ENV === 'production') { - // eslint-disable-next-line @typescript-eslint/no-require-imports - require('../public/tamagui.css') -} - -export function NextTamaguiProvider({ children }: { - children: React.ReactNode; -}) { - useServerInsertedHTML(() => { - // this first time this runs you'll get the full CSS including all themes - // after that, it will only return CSS generated since the last call - return <>{config.getNewCSS()} - }) - - return {children} -} \ No newline at end of file diff --git a/components/InputForm.tsx b/components/InputForm.tsx new file mode 100644 index 0000000..cf63355 --- /dev/null +++ b/components/InputForm.tsx @@ -0,0 +1,65 @@ +'use client' +import * as z from "zod" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" + +import { Button } from "@/components/ui/button" +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" + +const formSchema = z.object({ + clientName: z.string(), + redirectUris: z.string().url(), + scopes: z.string() +}) + +const InputForm = () => { + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + clientName: '', + redirectUris: '', + + }, + }) + + function onSubmit(values: z.infer) { + // Do something with the form values. + // ✅ This will be type-safe and validated. + console.log(values) + } + + return ( +
+ + ( + + Username + + + + + This is your public display name. + + + + )} + /> + + + + + ); +}; +export default InputForm; diff --git a/components/ui/button.tsx b/components/ui/button.tsx new file mode 100644 index 0000000..2ada851 --- /dev/null +++ b/components/ui/button.tsx @@ -0,0 +1,55 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "underline-offset-4 hover:underline text-primary", + }, + size: { + default: "h-10 py-2 px-4", + sm: "h-9 px-3 rounded-md", + lg: "h-11 px-8 rounded-md", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/components/ui/form.tsx b/components/ui/form.tsx new file mode 100644 index 0000000..4603f8b --- /dev/null +++ b/components/ui/form.tsx @@ -0,0 +1,176 @@ +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { Slot } from "@radix-ui/react-slot" +import { + Controller, + ControllerProps, + FieldPath, + FieldValues, + FormProvider, + useFormContext, +} from "react-hook-form" + +import { cn } from "@/lib/utils" +import { Label } from "@/components/ui/label" + +const Form = FormProvider + +type FormFieldContextValue< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +> = { + name: TName +} + +const FormFieldContext = React.createContext( + {} as FormFieldContextValue +) + +const FormField = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +>({ + ...props +}: ControllerProps) => { + return ( + + + + ) +} + +const useFormField = () => { + const fieldContext = React.useContext(FormFieldContext) + const itemContext = React.useContext(FormItemContext) + const { getFieldState, formState } = useFormContext() + + const fieldState = getFieldState(fieldContext.name, formState) + + if (!fieldContext) { + throw new Error("useFormField should be used within ") + } + + const { id } = itemContext + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} + +type FormItemContextValue = { + id: string +} + +const FormItemContext = React.createContext( + {} as FormItemContextValue +) + +const FormItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const id = React.useId() + + return ( + +
+ + ) +}) +FormItem.displayName = "FormItem" + +const FormLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + const { error, formItemId } = useFormField() + + return ( +