mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-12 10:21:39 +00:00
Compare commits
6 Commits
shadcn-ui@
...
shadcn/cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8392c7fa0c | ||
|
|
a465432a66 | ||
|
|
7822e06904 | ||
|
|
578d2c1823 | ||
|
|
29de71d77f | ||
|
|
0374ba874d |
@@ -5,7 +5,16 @@ const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
swcMinify: true,
|
||||
images: {
|
||||
domains: ["avatars.githubusercontent.com", "images.unsplash.com"],
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "avatars.githubusercontent.com",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "images.unsplash.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
redirects() {
|
||||
return [
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "pagination.tsx",
|
||||
"content": "import * as React from \"react\"\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ButtonProps, buttonVariants } from \"@/registry/default/ui/button\"\n\nconst Pagination = ({ className, ...props }: React.ComponentProps<\"nav\">) => (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n)\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n))\nPaginationContent.displayName = \"PaginationContent\"\n\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<\"li\">\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"\", className)} {...props} />\n))\nPaginationItem.displayName = \"PaginationItem\"\n\ntype PaginationLinkProps = {\n isActive?: boolean\n} & Pick<ButtonProps, \"size\"> &\n React.ComponentProps<\"a\">\n\nconst PaginationLink = ({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) => (\n <PaginationItem>\n <a\n aria-current={isActive ? \"page\" : undefined}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className\n )}\n {...props}\n />\n </PaginationItem>\n)\nPaginationLink.displayName = \"PaginationLink\"\n\nconst PaginationPrevious = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 pl-2.5\", className)}\n {...props}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n <span>Previous</span>\n </PaginationLink>\n)\nPaginationPrevious.displayName = \"PaginationPrevious\"\n\nconst PaginationNext = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 pr-2.5\", className)}\n {...props}\n >\n <span>Next</span>\n <ChevronRight className=\"h-4 w-4\" />\n </PaginationLink>\n)\n\nconst PaginationEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n)\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n}\n"
|
||||
"content": "import * as React from \"react\"\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ButtonProps, buttonVariants } from \"@/registry/default/ui/button\"\n\nconst Pagination = ({ className, ...props }: React.ComponentProps<\"nav\">) => (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n)\nPagination.displayName = \"Pagination\"\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n))\nPaginationContent.displayName = \"PaginationContent\"\n\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<\"li\">\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"\", className)} {...props} />\n))\nPaginationItem.displayName = \"PaginationItem\"\n\ntype PaginationLinkProps = {\n isActive?: boolean\n} & Pick<ButtonProps, \"size\"> &\n React.ComponentProps<\"a\">\n\nconst PaginationLink = ({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) => (\n <a\n aria-current={isActive ? \"page\" : undefined}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className\n )}\n {...props}\n />\n)\nPaginationLink.displayName = \"PaginationLink\"\n\nconst PaginationPrevious = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 pl-2.5\", className)}\n {...props}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n <span>Previous</span>\n </PaginationLink>\n)\nPaginationPrevious.displayName = \"PaginationPrevious\"\n\nconst PaginationNext = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 pr-2.5\", className)}\n {...props}\n >\n <span>Next</span>\n <ChevronRight className=\"h-4 w-4\" />\n </PaginationLink>\n)\nPaginationNext.displayName = \"PaginationNext\"\n\nconst PaginationEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n)\nPaginationEllipsis.displayName = \"PaginationEllipsis\"\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n}\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "pagination.tsx",
|
||||
"content": "import * as React from \"react\"\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n DotsHorizontalIcon,\n} from \"@radix-ui/react-icons\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ButtonProps, buttonVariants } from \"@/registry/new-york/ui/button\"\n\nconst Pagination = ({ className, ...props }: React.ComponentProps<\"nav\">) => (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n)\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n))\nPaginationContent.displayName = \"PaginationContent\"\n\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<\"li\">\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"\", className)} {...props} />\n))\nPaginationItem.displayName = \"PaginationItem\"\n\ntype PaginationLinkProps = {\n isActive?: boolean\n} & Pick<ButtonProps, \"size\"> &\n React.ComponentProps<\"a\">\n\nconst PaginationLink = ({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) => (\n <PaginationItem>\n <a\n aria-current={isActive ? \"page\" : undefined}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className\n )}\n {...props}\n />\n </PaginationItem>\n)\nPaginationLink.displayName = \"PaginationLink\"\n\nconst PaginationPrevious = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 pl-2.5\", className)}\n {...props}\n >\n <ChevronLeftIcon className=\"h-4 w-4\" />\n <span>Previous</span>\n </PaginationLink>\n)\nPaginationPrevious.displayName = \"PaginationPrevious\"\n\nconst PaginationNext = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 pr-2.5\", className)}\n {...props}\n >\n <span>Next</span>\n <ChevronRightIcon className=\"h-4 w-4\" />\n </PaginationLink>\n)\n\nconst PaginationEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <DotsHorizontalIcon className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n)\n\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n}\n"
|
||||
"content": "import * as React from \"react\"\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n DotsHorizontalIcon,\n} from \"@radix-ui/react-icons\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ButtonProps, buttonVariants } from \"@/registry/new-york/ui/button\"\n\nconst Pagination = ({ className, ...props }: React.ComponentProps<\"nav\">) => (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n)\nPagination.displayName = \"Pagination\"\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n))\nPaginationContent.displayName = \"PaginationContent\"\n\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<\"li\">\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"\", className)} {...props} />\n))\nPaginationItem.displayName = \"PaginationItem\"\n\ntype PaginationLinkProps = {\n isActive?: boolean\n} & Pick<ButtonProps, \"size\"> &\n React.ComponentProps<\"a\">\n\nconst PaginationLink = ({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) => (\n <a\n aria-current={isActive ? \"page\" : undefined}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className\n )}\n {...props}\n />\n)\nPaginationLink.displayName = \"PaginationLink\"\n\nconst PaginationPrevious = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 pl-2.5\", className)}\n {...props}\n >\n <ChevronLeftIcon className=\"h-4 w-4\" />\n <span>Previous</span>\n </PaginationLink>\n)\nPaginationPrevious.displayName = \"PaginationPrevious\"\n\nconst PaginationNext = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 pr-2.5\", className)}\n {...props}\n >\n <span>Next</span>\n <ChevronRightIcon className=\"h-4 w-4\" />\n </PaginationLink>\n)\nPaginationNext.displayName = \"PaginationNext\"\n\nconst PaginationEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <DotsHorizontalIcon className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n)\nPaginationEllipsis.displayName = \"PaginationEllipsis\"\n\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n}\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
@@ -2,18 +2,21 @@
|
||||
|
||||
import * as React from "react"
|
||||
import useEmblaCarousel, {
|
||||
type EmblaCarouselType as CarouselApi,
|
||||
type EmblaOptionsType as CarouselOptions,
|
||||
type EmblaPluginType as CarouselPlugin,
|
||||
type UseEmblaCarouselType,
|
||||
} from "embla-carousel-react"
|
||||
import { ArrowLeft, ArrowRight } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
|
||||
type CarouselApi = UseEmblaCarouselType[1]
|
||||
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
||||
type CarouselOptions = UseCarouselParameters[0]
|
||||
type CarouselPlugin = UseCarouselParameters[1]
|
||||
|
||||
type CarouselProps = {
|
||||
opts?: CarouselOptions
|
||||
plugins?: CarouselPlugin[]
|
||||
plugins?: CarouselPlugin
|
||||
orientation?: "horizontal" | "vertical"
|
||||
setApi?: (api: CarouselApi) => void
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
Pagination.displayName = "Pagination"
|
||||
|
||||
const PaginationContent = React.forwardRef<
|
||||
HTMLUListElement,
|
||||
@@ -44,19 +45,17 @@ const PaginationLink = ({
|
||||
size = "icon",
|
||||
...props
|
||||
}: PaginationLinkProps) => (
|
||||
<PaginationItem>
|
||||
<a
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: isActive ? "outline" : "ghost",
|
||||
size,
|
||||
}),
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PaginationItem>
|
||||
<a
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: isActive ? "outline" : "ghost",
|
||||
size,
|
||||
}),
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
PaginationLink.displayName = "PaginationLink"
|
||||
|
||||
@@ -90,6 +89,7 @@ const PaginationNext = ({
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</PaginationLink>
|
||||
)
|
||||
PaginationNext.displayName = "PaginationNext"
|
||||
|
||||
const PaginationEllipsis = ({
|
||||
className,
|
||||
@@ -104,6 +104,7 @@ const PaginationEllipsis = ({
|
||||
<span className="sr-only">More pages</span>
|
||||
</span>
|
||||
)
|
||||
PaginationEllipsis.displayName = "PaginationEllipsis"
|
||||
|
||||
export {
|
||||
Pagination,
|
||||
|
||||
@@ -3,17 +3,20 @@
|
||||
import * as React from "react"
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "@radix-ui/react-icons"
|
||||
import useEmblaCarousel, {
|
||||
type EmblaCarouselType as CarouselApi,
|
||||
type EmblaOptionsType as CarouselOptions,
|
||||
type EmblaPluginType as CarouselPlugin,
|
||||
type UseEmblaCarouselType,
|
||||
} from "embla-carousel-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button } from "@/registry/new-york/ui/button"
|
||||
|
||||
type CarouselApi = UseEmblaCarouselType[1]
|
||||
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
||||
type CarouselOptions = UseCarouselParameters[0]
|
||||
type CarouselPlugin = UseCarouselParameters[1]
|
||||
|
||||
type CarouselProps = {
|
||||
opts?: CarouselOptions
|
||||
plugins?: CarouselPlugin[]
|
||||
plugins?: CarouselPlugin
|
||||
orientation?: "horizontal" | "vertical"
|
||||
setApi?: (api: CarouselApi) => void
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
Pagination.displayName = "Pagination"
|
||||
|
||||
const PaginationContent = React.forwardRef<
|
||||
HTMLUListElement,
|
||||
@@ -48,19 +49,17 @@ const PaginationLink = ({
|
||||
size = "icon",
|
||||
...props
|
||||
}: PaginationLinkProps) => (
|
||||
<PaginationItem>
|
||||
<a
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: isActive ? "outline" : "ghost",
|
||||
size,
|
||||
}),
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PaginationItem>
|
||||
<a
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: isActive ? "outline" : "ghost",
|
||||
size,
|
||||
}),
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
PaginationLink.displayName = "PaginationLink"
|
||||
|
||||
@@ -94,6 +93,7 @@ const PaginationNext = ({
|
||||
<ChevronRightIcon className="h-4 w-4" />
|
||||
</PaginationLink>
|
||||
)
|
||||
PaginationNext.displayName = "PaginationNext"
|
||||
|
||||
const PaginationEllipsis = ({
|
||||
className,
|
||||
@@ -108,6 +108,7 @@ const PaginationEllipsis = ({
|
||||
<span className="sr-only">More pages</span>
|
||||
</span>
|
||||
)
|
||||
PaginationEllipsis.displayName = "PaginationEllipsis"
|
||||
|
||||
export {
|
||||
Pagination,
|
||||
|
||||
@@ -60,7 +60,6 @@ const ui: Registry = [
|
||||
files: ["ui/carousel.tsx"],
|
||||
registryDependencies: ["button"],
|
||||
dependencies: ["embla-carousel-react"],
|
||||
devDependencies: ["embla-carousel"],
|
||||
},
|
||||
{
|
||||
name: "checkbox",
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
"build:cli": "turbo --filter=shadcn-ui build",
|
||||
"build:registry": "pnpm --filter=www build:registry",
|
||||
"dev": "turbo run dev --parallel",
|
||||
"dev:cli": "turbo --filter=shadcn-ui dev",
|
||||
"start:cli": "pnpm --filter=shadcn-ui start:dev",
|
||||
"cli:dev": "turbo --filter=shadcn-ui dev",
|
||||
"cli:start": "pnpm --filter=shadcn-ui start:dev",
|
||||
"www:dev": "pnpm --filter=www dev",
|
||||
"lint": "turbo run lint",
|
||||
"lint:fix": "turbo run lint:fix",
|
||||
"preview": "turbo run preview",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @shadcn/ui
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2454](https://github.com/shadcn-ui/ui/pull/2454) [`0374ba8`](https://github.com/shadcn-ui/ui/commit/0374ba874d1c76ae08660c655aea6cdf7a7817f6) Thanks [@shadcn](https://github.com/shadcn)! - add automatic config detection for Next.js
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "shadcn-ui",
|
||||
"version": "0.7.0",
|
||||
"version": "0.8.0",
|
||||
"description": "Add components to your apps.",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -53,6 +53,7 @@
|
||||
"cosmiconfig": "^8.1.3",
|
||||
"diff": "^5.1.0",
|
||||
"execa": "^7.0.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"fs-extra": "^11.1.0",
|
||||
"https-proxy-agent": "^6.2.0",
|
||||
"lodash.template": "^4.5.0",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { existsSync, promises as fs } from "fs"
|
||||
import path from "path"
|
||||
import { applyCSSUpdates } from "@/src/utils/css"
|
||||
import {
|
||||
DEFAULT_COMPONENTS,
|
||||
DEFAULT_TAILWIND_CONFIG,
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
type Config,
|
||||
} from "@/src/utils/get-config"
|
||||
import { getPackageManager } from "@/src/utils/get-package-manager"
|
||||
import { getProjectConfig, preFlight } from "@/src/utils/get-project-info"
|
||||
import { handleError } from "@/src/utils/handle-error"
|
||||
import { logger } from "@/src/utils/logger"
|
||||
import {
|
||||
@@ -39,12 +41,14 @@ const PROJECT_DEPENDENCIES = [
|
||||
const initOptionsSchema = z.object({
|
||||
cwd: z.string(),
|
||||
yes: z.boolean(),
|
||||
defaults: z.boolean(),
|
||||
})
|
||||
|
||||
export const init = new Command()
|
||||
.name("init")
|
||||
.description("initialize your project and install dependencies")
|
||||
.option("-y, --yes", "skip confirmation prompt.", false)
|
||||
.option("-d, --defaults,", "use default configuration.", false)
|
||||
.option(
|
||||
"-c, --cwd <cwd>",
|
||||
"the working directory. defaults to the current directory.",
|
||||
@@ -61,15 +65,28 @@ export const init = new Command()
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Read config.
|
||||
const existingConfig = await getConfig(cwd)
|
||||
const config = await promptForConfig(cwd, existingConfig, options.yes)
|
||||
preFlight(cwd)
|
||||
|
||||
await runInit(cwd, config)
|
||||
const projectConfig = await getProjectConfig(cwd)
|
||||
if (projectConfig) {
|
||||
const config = await promptForMinimalConfig(
|
||||
cwd,
|
||||
projectConfig,
|
||||
opts.defaults
|
||||
)
|
||||
await runInit(cwd, config)
|
||||
} else {
|
||||
// Read config.
|
||||
const existingConfig = await getConfig(cwd)
|
||||
const config = await promptForConfig(cwd, existingConfig, options.yes)
|
||||
await runInit(cwd, config)
|
||||
}
|
||||
|
||||
logger.info("")
|
||||
logger.info(
|
||||
`${chalk.green("Success!")} Project initialization completed.`
|
||||
`${chalk.green(
|
||||
"Success!"
|
||||
)} Project initialization completed. You may now add components.`
|
||||
)
|
||||
logger.info("")
|
||||
} catch (error) {
|
||||
@@ -213,6 +230,81 @@ export async function promptForConfig(
|
||||
return await resolveConfigPaths(cwd, config)
|
||||
}
|
||||
|
||||
export async function promptForMinimalConfig(
|
||||
cwd: string,
|
||||
defaultConfig: Config,
|
||||
defaults = false
|
||||
) {
|
||||
const highlight = (text: string) => chalk.cyan(text)
|
||||
let style = defaultConfig.style
|
||||
let baseColor = defaultConfig.tailwind.baseColor
|
||||
let cssVariables = defaultConfig.tailwind.cssVariables
|
||||
|
||||
if (!defaults) {
|
||||
const styles = await getRegistryStyles()
|
||||
const baseColors = await getRegistryBaseColors()
|
||||
|
||||
const options = await prompts([
|
||||
{
|
||||
type: "select",
|
||||
name: "style",
|
||||
message: `Which ${highlight("style")} would you like to use?`,
|
||||
choices: styles.map((style) => ({
|
||||
title: style.label,
|
||||
value: style.name,
|
||||
})),
|
||||
},
|
||||
{
|
||||
type: "select",
|
||||
name: "tailwindBaseColor",
|
||||
message: `Which color would you like to use as ${highlight(
|
||||
"base color"
|
||||
)}?`,
|
||||
choices: baseColors.map((color) => ({
|
||||
title: color.label,
|
||||
value: color.name,
|
||||
})),
|
||||
},
|
||||
{
|
||||
type: "toggle",
|
||||
name: "tailwindCssVariables",
|
||||
message: `Would you like to use ${highlight(
|
||||
"CSS variables"
|
||||
)} for colors?`,
|
||||
initial: defaultConfig?.tailwind.cssVariables,
|
||||
active: "yes",
|
||||
inactive: "no",
|
||||
},
|
||||
])
|
||||
|
||||
style = options.style
|
||||
baseColor = options.tailwindBaseColor
|
||||
cssVariables = options.tailwindCssVariables
|
||||
}
|
||||
|
||||
const config = rawConfigSchema.parse({
|
||||
$schema: defaultConfig?.$schema,
|
||||
style,
|
||||
tailwind: {
|
||||
...defaultConfig?.tailwind,
|
||||
baseColor,
|
||||
cssVariables,
|
||||
},
|
||||
rsc: defaultConfig?.rsc,
|
||||
tsx: defaultConfig?.tsx,
|
||||
aliases: defaultConfig?.aliases,
|
||||
})
|
||||
|
||||
// Write to file.
|
||||
logger.info("")
|
||||
const spinner = ora(`Writing components.json...`).start()
|
||||
const targetPath = path.resolve(cwd, "components.json")
|
||||
await fs.writeFile(targetPath, JSON.stringify(config, null, 2), "utf8")
|
||||
spinner.succeed()
|
||||
|
||||
return await resolveConfigPaths(cwd, config)
|
||||
}
|
||||
|
||||
export async function runInit(cwd: string, config: Config) {
|
||||
const spinner = ora(`Initializing project...`)?.start()
|
||||
|
||||
@@ -266,16 +358,17 @@ export async function runInit(cwd: string, config: Config) {
|
||||
|
||||
// Write css file.
|
||||
const baseColor = await getRegistryBaseColor(config.tailwind.baseColor)
|
||||
|
||||
if (baseColor) {
|
||||
await fs.writeFile(
|
||||
const cssFileInput = await fs.readFile(
|
||||
config.resolvedPaths.tailwindCss,
|
||||
config.tailwind.cssVariables
|
||||
? config.tailwind.prefix
|
||||
? applyPrefixesCss(baseColor.cssVarsTemplate, config.tailwind.prefix)
|
||||
: baseColor.cssVarsTemplate
|
||||
: baseColor.inlineColorsTemplate,
|
||||
"utf8"
|
||||
)
|
||||
// const cssFileTemplate = config.tailwind.cssVariables
|
||||
// ? baseColor.cssVarsTemplate
|
||||
// : baseColor.inlineColorsTemplate
|
||||
const cssFileContent = applyCSSUpdates(cssFileInput, baseColor, config)
|
||||
await fs.writeFile(config.resolvedPaths.tailwindCss, cssFileContent, "utf8")
|
||||
}
|
||||
|
||||
// Write cn file.
|
||||
|
||||
86
packages/cli/src/utils/css.ts
Normal file
86
packages/cli/src/utils/css.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { Config } from "@/src/utils/get-config"
|
||||
import { registryBaseColorSchema } from "@/src/utils/registry/schema"
|
||||
import { applyPrefixesCss } from "@/src/utils/transformers/transform-tw-prefix"
|
||||
import * as z from "zod"
|
||||
|
||||
// This does a simple string replacement.
|
||||
// TODO: Do we want to use a proper CSS transformer here? Probably not right now.
|
||||
export function applyCSSUpdates(
|
||||
input: string,
|
||||
baseColor: Pick<z.infer<typeof registryBaseColorSchema>, "cssVars">,
|
||||
config: Partial<Config>
|
||||
) {
|
||||
if (!isCSSUpdateRequired(input, config)) {
|
||||
return input
|
||||
}
|
||||
|
||||
let output = input
|
||||
// Check if the file contains the `@tailwind` directives.
|
||||
// We assume it does since Tailwind CSS is checked in preflight.
|
||||
if (!input.includes("@tailwind base")) {
|
||||
// Prepend the `@tailwind` directives.
|
||||
output = `@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n${input}`
|
||||
}
|
||||
|
||||
// No additional changes if not using CSS variables.
|
||||
if (!config.tailwind?.cssVariables) {
|
||||
return output
|
||||
}
|
||||
|
||||
const lightColors = Object.entries(baseColor.cssVars.light).map(
|
||||
([name, value]) => ` --${name}: ${value};`
|
||||
)
|
||||
const darkColors = Object.entries(baseColor.cssVars.dark).map(
|
||||
([name, value]) => ` --${name}: ${value};`
|
||||
)
|
||||
|
||||
output = output.replace(
|
||||
/@tailwind utilities;/,
|
||||
`@tailwind utilities;\n
|
||||
@layer base {
|
||||
:root {
|
||||
${lightColors.join("\n")}
|
||||
}
|
||||
|
||||
.dark {
|
||||
${darkColors.join("\n")}
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}`
|
||||
)
|
||||
|
||||
if (config.tailwind.prefix) {
|
||||
output = applyPrefixesCss(output, config.tailwind.prefix)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
function isCSSUpdateRequired(input: string, config: Partial<Config>) {
|
||||
// Check for tailwind directives.
|
||||
const hasTailwindDirectives =
|
||||
input.includes("@tailwind base") &&
|
||||
input.includes("@tailwind utilities") &&
|
||||
input.includes("@tailwind components")
|
||||
|
||||
// If we're not using CSS variables, we only check for the `@tailwind` directives.
|
||||
if (!config.tailwind?.cssVariables) {
|
||||
return !hasTailwindDirectives
|
||||
}
|
||||
|
||||
// If we are using CSS variables, we check for the `@layer base` directives.
|
||||
// And we check for the `--background` and `--foreground` variables.
|
||||
return !(
|
||||
input.includes("@layer base") &&
|
||||
input.includes("--background") &&
|
||||
input.includes("--foreground")
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,33 @@
|
||||
import { existsSync } from "fs"
|
||||
import path from "path"
|
||||
import fs from "fs-extra"
|
||||
import {
|
||||
Config,
|
||||
RawConfig,
|
||||
getConfig,
|
||||
resolveConfigPaths,
|
||||
} from "@/src/utils/get-config"
|
||||
import fg from "fast-glob"
|
||||
import fs, { pathExists } from "fs-extra"
|
||||
import { loadConfig } from "tsconfig-paths"
|
||||
|
||||
// TODO: Add support for more frameworks.
|
||||
// We'll start with Next.js for now.
|
||||
const PROJECT_TYPES = [
|
||||
"next-app",
|
||||
"next-app-src",
|
||||
"next-pages",
|
||||
"next-pages-src",
|
||||
] as const
|
||||
|
||||
type ProjectType = (typeof PROJECT_TYPES)[number]
|
||||
|
||||
const PROJECT_SHARED_IGNORE = [
|
||||
"**/node_modules/**",
|
||||
".next",
|
||||
"public",
|
||||
"dist",
|
||||
"build",
|
||||
]
|
||||
|
||||
export async function getProjectInfo() {
|
||||
const info = {
|
||||
@@ -42,3 +69,126 @@ export async function getTsConfig() {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export async function getProjectConfig(cwd: string): Promise<Config | null> {
|
||||
// Check for existing component config.
|
||||
const existingConfig = await getConfig(cwd)
|
||||
if (existingConfig) {
|
||||
return existingConfig
|
||||
}
|
||||
|
||||
const projectType = await getProjectType(cwd)
|
||||
const tailwindCssFile = await getTailwindCssFile(cwd)
|
||||
const tsConfigAliasPrefix = await getTsConfigAliasPrefix(cwd)
|
||||
|
||||
if (!projectType || !tailwindCssFile || !tsConfigAliasPrefix) {
|
||||
return null
|
||||
}
|
||||
|
||||
const isTsx = await isTypeScriptProject(cwd)
|
||||
|
||||
const config: RawConfig = {
|
||||
$schema: "https://ui.shadcn.com/schema.json",
|
||||
rsc: ["next-app", "next-app-src"].includes(projectType),
|
||||
tsx: isTsx,
|
||||
style: "new-york",
|
||||
tailwind: {
|
||||
config: isTsx ? "tailwind.config.ts" : "tailwind.config.js",
|
||||
baseColor: "zinc",
|
||||
css: tailwindCssFile,
|
||||
cssVariables: true,
|
||||
prefix: "",
|
||||
},
|
||||
aliases: {
|
||||
utils: `${tsConfigAliasPrefix}/lib/utils`,
|
||||
components: `${tsConfigAliasPrefix}/components`,
|
||||
},
|
||||
}
|
||||
|
||||
return await resolveConfigPaths(cwd, config)
|
||||
}
|
||||
|
||||
export async function getProjectType(cwd: string): Promise<ProjectType | null> {
|
||||
const files = await fg.glob("**/*", {
|
||||
cwd,
|
||||
deep: 3,
|
||||
ignore: PROJECT_SHARED_IGNORE,
|
||||
})
|
||||
|
||||
const isNextProject = files.find((file) => file.startsWith("next.config."))
|
||||
if (!isNextProject) {
|
||||
return null
|
||||
}
|
||||
|
||||
const isUsingSrcDir = await fs.pathExists(path.resolve(cwd, "src"))
|
||||
const isUsingAppDir = await fs.pathExists(
|
||||
path.resolve(cwd, `${isUsingSrcDir ? "src/" : ""}app`)
|
||||
)
|
||||
|
||||
if (isUsingAppDir) {
|
||||
return isUsingSrcDir ? "next-app-src" : "next-app"
|
||||
}
|
||||
|
||||
return isUsingSrcDir ? "next-pages-src" : "next-pages"
|
||||
}
|
||||
|
||||
export async function getTailwindCssFile(cwd: string) {
|
||||
const files = await fg.glob("**/*.css", {
|
||||
cwd,
|
||||
deep: 3,
|
||||
ignore: PROJECT_SHARED_IGNORE,
|
||||
})
|
||||
|
||||
if (!files.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (const file of files) {
|
||||
const contents = await fs.readFile(path.resolve(cwd, file), "utf8")
|
||||
// Assume that if the file contains `@tailwind base` it's the main css file.
|
||||
if (contents.includes("@tailwind base")) {
|
||||
return file
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export async function getTsConfigAliasPrefix(cwd: string) {
|
||||
const tsConfig = await loadConfig(cwd)
|
||||
|
||||
if (tsConfig?.resultType === "failed" || !tsConfig?.paths) {
|
||||
return null
|
||||
}
|
||||
|
||||
// This assume that the first alias is the prefix.
|
||||
for (const [alias, paths] of Object.entries(tsConfig.paths)) {
|
||||
if (paths.includes("./*") || paths.includes("./src/*")) {
|
||||
return alias.at(0)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export async function isTypeScriptProject(cwd: string) {
|
||||
// Check if cwd has a tsconfig.json file.
|
||||
return pathExists(path.resolve(cwd, "tsconfig.json"))
|
||||
}
|
||||
|
||||
export async function preFlight(cwd: string) {
|
||||
// We need Tailwind CSS to be configured.
|
||||
const tailwindConfig = await fg.glob("tailwind.config.*", {
|
||||
cwd,
|
||||
deep: 3,
|
||||
ignore: PROJECT_SHARED_IGNORE,
|
||||
})
|
||||
|
||||
if (!tailwindConfig.length) {
|
||||
throw new Error(
|
||||
"Tailwind CSS is not installed. Visit https://tailwindcss.com/docs/installation to get started."
|
||||
)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
27
packages/cli/test/fixtures/css/app-globals.css
vendored
Normal file
27
packages/cli/test/fixtures/css/app-globals.css
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
38
packages/cli/test/fixtures/css/applied-css-vars.css
vendored
Normal file
38
packages/cli/test/fixtures/css/applied-css-vars.css
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
--primary: 220.9 39.3% 11%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
--ring: 224 71.4% 4.1%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
--primary: 210 20% 98%;
|
||||
--primary-foreground: 220.9 39.3% 11%;
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
--ring: 216 12.2% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: tomato;
|
||||
}
|
||||
7
packages/cli/test/fixtures/css/applied.css
vendored
Normal file
7
packages/cli/test/fixtures/css/applied.css
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
background-color: tomato;
|
||||
}
|
||||
3
packages/cli/test/fixtures/css/no-tailwind.css
vendored
Normal file
3
packages/cli/test/fixtures/css/no-tailwind.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: tomato;
|
||||
}
|
||||
BIN
packages/cli/test/fixtures/next-app-js/app/favicon.ico
vendored
Normal file
BIN
packages/cli/test/fixtures/next-app-js/app/favicon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
27
packages/cli/test/fixtures/next-app-js/app/globals.css
vendored
Normal file
27
packages/cli/test/fixtures/next-app-js/app/globals.css
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
17
packages/cli/test/fixtures/next-app-js/app/layout.js
vendored
Normal file
17
packages/cli/test/fixtures/next-app-js/app/layout.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Inter } from 'next/font/google'
|
||||
import './globals.css'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
export const metadata = {
|
||||
title: 'Create Next App',
|
||||
description: 'Generated by create next app',
|
||||
}
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
113
packages/cli/test/fixtures/next-app-js/app/page.js
vendored
Normal file
113
packages/cli/test/fixtures/next-app-js/app/page.js
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
import Image from 'next/image'
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
||||
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
|
||||
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
|
||||
Get started by editing
|
||||
<code className="font-mono font-bold">app/page.js</code>
|
||||
</p>
|
||||
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
|
||||
<a
|
||||
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
By{' '}
|
||||
<Image
|
||||
src="/vercel.svg"
|
||||
alt="Vercel Logo"
|
||||
className="dark:invert"
|
||||
width={100}
|
||||
height={24}
|
||||
priority
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
|
||||
<Image
|
||||
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js Logo"
|
||||
width={180}
|
||||
height={37}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
|
||||
<a
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Docs{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Find in-depth information about Next.js features and API.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800 hover:dark:bg-opacity-30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Learn{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Learn about Next.js in an interactive course with quizzes!
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Templates{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Explore starter templates for Next.js.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Deploy{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Instantly deploy your Next.js site to a shareable URL with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
7
packages/cli/test/fixtures/next-app-js/jsconfig.json
vendored
Normal file
7
packages/cli/test/fixtures/next-app-js/jsconfig.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
4
packages/cli/test/fixtures/next-app-js/next.config.js
vendored
Normal file
4
packages/cli/test/fixtures/next-app-js/next.config.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {}
|
||||
|
||||
module.exports = nextConfig
|
||||
23
packages/cli/test/fixtures/next-app-js/package.json
vendored
Normal file
23
packages/cli/test/fixtures/next-app-js/package.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "app-js",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"next": "14.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.0.1",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.0.4"
|
||||
}
|
||||
}
|
||||
6
packages/cli/test/fixtures/next-app-js/postcss.config.js
vendored
Normal file
6
packages/cli/test/fixtures/next-app-js/postcss.config.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
18
packages/cli/test/fixtures/next-app-js/tailwind.config.js
vendored
Normal file
18
packages/cli/test/fixtures/next-app-js/tailwind.config.js
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic':
|
||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
5
packages/cli/test/fixtures/next-app-src/next-env.d.ts
vendored
Normal file
5
packages/cli/test/fixtures/next-app-src/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
4
packages/cli/test/fixtures/next-app-src/next.config.js
vendored
Normal file
4
packages/cli/test/fixtures/next-app-src/next.config.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {}
|
||||
|
||||
module.exports = nextConfig
|
||||
3
packages/cli/test/fixtures/next-app-src/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-app-src/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
11
packages/cli/test/fixtures/next-app-src/package.json
vendored
Normal file
11
packages/cli/test/fixtures/next-app-src/package.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "test-cli-next-app-src",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
}
|
||||
}
|
||||
2620
packages/cli/test/fixtures/next-app-src/pnpm-lock.yaml
generated
vendored
Normal file
2620
packages/cli/test/fixtures/next-app-src/pnpm-lock.yaml
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
packages/cli/test/fixtures/next-app-src/postcss.config.js
vendored
Normal file
6
packages/cli/test/fixtures/next-app-src/postcss.config.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
BIN
packages/cli/test/fixtures/next-app-src/src/app/favicon.ico
vendored
Normal file
BIN
packages/cli/test/fixtures/next-app-src/src/app/favicon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
13
packages/cli/test/fixtures/next-app-src/src/app/layout.tsx
vendored
Normal file
13
packages/cli/test/fixtures/next-app-src/src/app/layout.tsx
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import "./styles.css"
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
3
packages/cli/test/fixtures/next-app-src/src/app/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-app-src/src/app/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
113
packages/cli/test/fixtures/next-app-src/src/app/page.tsx
vendored
Normal file
113
packages/cli/test/fixtures/next-app-src/src/app/page.tsx
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
import Image from 'next/image'
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
||||
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
|
||||
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
|
||||
Get started by editing
|
||||
<code className="font-mono font-bold">src/app/page.tsx</code>
|
||||
</p>
|
||||
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
|
||||
<a
|
||||
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
By{' '}
|
||||
<Image
|
||||
src="/vercel.svg"
|
||||
alt="Vercel Logo"
|
||||
className="dark:invert"
|
||||
width={100}
|
||||
height={24}
|
||||
priority
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
|
||||
<Image
|
||||
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js Logo"
|
||||
width={180}
|
||||
height={37}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
|
||||
<a
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Docs{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Find in-depth information about Next.js features and API.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Learn{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Learn about Next.js in an interactive course with quizzes!
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Templates{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Explore the Next.js 13 playground.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Deploy{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Instantly deploy your Next.js site to a shareable URL with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
27
packages/cli/test/fixtures/next-app-src/src/app/styles.css
vendored
Normal file
27
packages/cli/test/fixtures/next-app-src/src/app/styles.css
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
3
packages/cli/test/fixtures/next-app-src/src/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-app-src/src/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
21
packages/cli/test/fixtures/next-app-src/tailwind.config.ts
vendored
Normal file
21
packages/cli/test/fixtures/next-app-src/tailwind.config.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// @ts-nocheck
|
||||
import type { Config } from 'tailwindcss'
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/app/**/*.{js,ts,jsx,tsx,mdx}'
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic':
|
||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: []
|
||||
}
|
||||
export default config
|
||||
27
packages/cli/test/fixtures/next-app-src/tsconfig.json
vendored
Normal file
27
packages/cli/test/fixtures/next-app-src/tsconfig.json
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"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"]
|
||||
}
|
||||
BIN
packages/cli/test/fixtures/next-app/app/favicon.ico
vendored
Normal file
BIN
packages/cli/test/fixtures/next-app/app/favicon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
27
packages/cli/test/fixtures/next-app/app/globals.css
vendored
Normal file
27
packages/cli/test/fixtures/next-app/app/globals.css
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
22
packages/cli/test/fixtures/next-app/app/layout.tsx
vendored
Normal file
22
packages/cli/test/fixtures/next-app/app/layout.tsx
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import './globals.css'
|
||||
import type { Metadata } from 'next'
|
||||
import { Inter } from 'next/font/google'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Create Next App',
|
||||
description: 'Generated by create next app',
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
3
packages/cli/test/fixtures/next-app/app/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-app/app/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
113
packages/cli/test/fixtures/next-app/app/page.tsx
vendored
Normal file
113
packages/cli/test/fixtures/next-app/app/page.tsx
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
import Image from 'next/image'
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
||||
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
|
||||
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
|
||||
Get started by editing
|
||||
<code className="font-mono font-bold">app/page.tsx</code>
|
||||
</p>
|
||||
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
|
||||
<a
|
||||
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
By{' '}
|
||||
<Image
|
||||
src="/vercel.svg"
|
||||
alt="Vercel Logo"
|
||||
className="dark:invert"
|
||||
width={100}
|
||||
height={24}
|
||||
priority
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
|
||||
<Image
|
||||
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js Logo"
|
||||
width={180}
|
||||
height={37}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
|
||||
<a
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Docs{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Find in-depth information about Next.js features and API.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Learn{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Learn about Next.js in an interactive course with quizzes!
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Templates{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Explore the Next.js 13 playground.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Deploy{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Instantly deploy your Next.js site to a shareable URL with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
5
packages/cli/test/fixtures/next-app/next-env.d.ts
vendored
Normal file
5
packages/cli/test/fixtures/next-app/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
4
packages/cli/test/fixtures/next-app/next.config.js
vendored
Normal file
4
packages/cli/test/fixtures/next-app/next.config.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {}
|
||||
|
||||
module.exports = nextConfig
|
||||
11
packages/cli/test/fixtures/next-app/package.json
vendored
Normal file
11
packages/cli/test/fixtures/next-app/package.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "test-cli-next-app",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
}
|
||||
}
|
||||
2620
packages/cli/test/fixtures/next-app/pnpm-lock.yaml
generated
vendored
Normal file
2620
packages/cli/test/fixtures/next-app/pnpm-lock.yaml
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
packages/cli/test/fixtures/next-app/postcss.config.js
vendored
Normal file
6
packages/cli/test/fixtures/next-app/postcss.config.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
21
packages/cli/test/fixtures/next-app/tailwind.config.ts
vendored
Normal file
21
packages/cli/test/fixtures/next-app/tailwind.config.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// @ts-nocheck
|
||||
import type { Config } from 'tailwindcss'
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./app/**/*.{js,ts,jsx,tsx,mdx}'
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic':
|
||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: []
|
||||
}
|
||||
export default config
|
||||
27
packages/cli/test/fixtures/next-app/tsconfig.json
vendored
Normal file
27
packages/cli/test/fixtures/next-app/tsconfig.json
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"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
packages/cli/test/fixtures/next-pages-src/next-env.d.ts
vendored
Normal file
5
packages/cli/test/fixtures/next-pages-src/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
6
packages/cli/test/fixtures/next-pages-src/next.config.js
vendored
Normal file
6
packages/cli/test/fixtures/next-pages-src/next.config.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
}
|
||||
|
||||
module.exports = nextConfig
|
||||
3
packages/cli/test/fixtures/next-pages-src/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-pages-src/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
11
packages/cli/test/fixtures/next-pages-src/package.json
vendored
Normal file
11
packages/cli/test/fixtures/next-pages-src/package.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "test-pages-src",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
}
|
||||
}
|
||||
2620
packages/cli/test/fixtures/next-pages-src/pnpm-lock.yaml
generated
vendored
Normal file
2620
packages/cli/test/fixtures/next-pages-src/pnpm-lock.yaml
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
packages/cli/test/fixtures/next-pages-src/postcss.config.js
vendored
Normal file
6
packages/cli/test/fixtures/next-pages-src/postcss.config.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
3
packages/cli/test/fixtures/next-pages-src/src/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-pages-src/src/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
6
packages/cli/test/fixtures/next-pages-src/src/pages/_app.tsx
vendored
Normal file
6
packages/cli/test/fixtures/next-pages-src/src/pages/_app.tsx
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import '@/styles/globals.css'
|
||||
import type { AppProps } from 'next/app'
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
13
packages/cli/test/fixtures/next-pages-src/src/pages/_document.tsx
vendored
Normal file
13
packages/cli/test/fixtures/next-pages-src/src/pages/_document.tsx
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Html, Head, Main, NextScript } from 'next/document'
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head />
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
13
packages/cli/test/fixtures/next-pages-src/src/pages/api/hello.ts
vendored
Normal file
13
packages/cli/test/fixtures/next-pages-src/src/pages/api/hello.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
type Data = {
|
||||
name: string
|
||||
}
|
||||
|
||||
export default function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<Data>
|
||||
) {
|
||||
res.status(200).json({ name: 'John Doe' })
|
||||
}
|
||||
118
packages/cli/test/fixtures/next-pages-src/src/pages/index.tsx
vendored
Normal file
118
packages/cli/test/fixtures/next-pages-src/src/pages/index.tsx
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
import Image from 'next/image'
|
||||
import { Inter } from 'next/font/google'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main
|
||||
className={`flex min-h-screen flex-col items-center justify-between p-24 ${inter.className}`}
|
||||
>
|
||||
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
|
||||
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
|
||||
Get started by editing
|
||||
<code className="font-mono font-bold">src/pages/index.tsx</code>
|
||||
</p>
|
||||
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
|
||||
<a
|
||||
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
By{' '}
|
||||
<Image
|
||||
src="/vercel.svg"
|
||||
alt="Vercel Logo"
|
||||
className="dark:invert"
|
||||
width={100}
|
||||
height={24}
|
||||
priority
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700/10 after:dark:from-sky-900 after:dark:via-[#0141ff]/40 before:lg:h-[360px]">
|
||||
<Image
|
||||
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js Logo"
|
||||
width={180}
|
||||
height={37}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
|
||||
<a
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Docs{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Find in-depth information about Next.js features and API.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Learn{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Learn about Next.js in an interactive course with quizzes!
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Templates{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Discover and deploy boilerplate example Next.js projects.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Deploy{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Instantly deploy your Next.js site to a shareable URL with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
3
packages/cli/test/fixtures/next-pages-src/src/pages/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-pages-src/src/pages/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
27
packages/cli/test/fixtures/next-pages-src/src/styles/globals.css
vendored
Normal file
27
packages/cli/test/fixtures/next-pages-src/src/styles/globals.css
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
3
packages/cli/test/fixtures/next-pages-src/src/styles/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-pages-src/src/styles/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
21
packages/cli/test/fixtures/next-pages-src/tailwind.config.ts
vendored
Normal file
21
packages/cli/test/fixtures/next-pages-src/tailwind.config.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// @ts-nocheck
|
||||
import type { Config } from 'tailwindcss'
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/app/**/*.{js,ts,jsx,tsx,mdx}'
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic':
|
||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: []
|
||||
}
|
||||
export default config
|
||||
22
packages/cli/test/fixtures/next-pages-src/tsconfig.json
vendored
Normal file
22
packages/cli/test/fixtures/next-pages-src/tsconfig.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
6
packages/cli/test/fixtures/next-pages/next.config.js
vendored
Normal file
6
packages/cli/test/fixtures/next-pages/next.config.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
}
|
||||
|
||||
module.exports = nextConfig
|
||||
11
packages/cli/test/fixtures/next-pages/package.json
vendored
Normal file
11
packages/cli/test/fixtures/next-pages/package.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "test-cli-pages",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
}
|
||||
}
|
||||
6
packages/cli/test/fixtures/next-pages/pages/_app.tsx
vendored
Normal file
6
packages/cli/test/fixtures/next-pages/pages/_app.tsx
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import '~/styles/globals.css'
|
||||
import type { AppProps } from 'next/app'
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
13
packages/cli/test/fixtures/next-pages/pages/_document.tsx
vendored
Normal file
13
packages/cli/test/fixtures/next-pages/pages/_document.tsx
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Html, Head, Main, NextScript } from 'next/document'
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head />
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
13
packages/cli/test/fixtures/next-pages/pages/api/hello.ts
vendored
Normal file
13
packages/cli/test/fixtures/next-pages/pages/api/hello.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
type Data = {
|
||||
name: string
|
||||
}
|
||||
|
||||
export default function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<Data>
|
||||
) {
|
||||
res.status(200).json({ name: 'John Doe' })
|
||||
}
|
||||
118
packages/cli/test/fixtures/next-pages/pages/index.tsx
vendored
Normal file
118
packages/cli/test/fixtures/next-pages/pages/index.tsx
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
import Image from 'next/image'
|
||||
import { Inter } from 'next/font/google'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main
|
||||
className={`flex min-h-screen flex-col items-center justify-between p-24 ${inter.className}`}
|
||||
>
|
||||
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
|
||||
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
|
||||
Get started by editing
|
||||
<code className="font-mono font-bold">pages/index.tsx</code>
|
||||
</p>
|
||||
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
|
||||
<a
|
||||
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
By{' '}
|
||||
<Image
|
||||
src="/vercel.svg"
|
||||
alt="Vercel Logo"
|
||||
className="dark:invert"
|
||||
width={100}
|
||||
height={24}
|
||||
priority
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700/10 after:dark:from-sky-900 after:dark:via-[#0141ff]/40 before:lg:h-[360px]">
|
||||
<Image
|
||||
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js Logo"
|
||||
width={180}
|
||||
height={37}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
|
||||
<a
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Docs{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Find in-depth information about Next.js features and API.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Learn{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Learn about Next.js in an interactive course with quizzes!
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Templates{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Discover and deploy boilerplate example Next.js projects.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Deploy{' '}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Instantly deploy your Next.js site to a shareable URL with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
3
packages/cli/test/fixtures/next-pages/pages/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-pages/pages/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
2620
packages/cli/test/fixtures/next-pages/pnpm-lock.yaml
generated
vendored
Normal file
2620
packages/cli/test/fixtures/next-pages/pnpm-lock.yaml
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
packages/cli/test/fixtures/next-pages/postcss.config.js
vendored
Normal file
6
packages/cli/test/fixtures/next-pages/postcss.config.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
27
packages/cli/test/fixtures/next-pages/styles/globals.css
vendored
Normal file
27
packages/cli/test/fixtures/next-pages/styles/globals.css
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
3
packages/cli/test/fixtures/next-pages/styles/other.css
vendored
Normal file
3
packages/cli/test/fixtures/next-pages/styles/other.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: red;
|
||||
}
|
||||
21
packages/cli/test/fixtures/next-pages/tailwind.config.ts
vendored
Normal file
21
packages/cli/test/fixtures/next-pages/tailwind.config.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// @ts-nocheck
|
||||
import type { Config } from 'tailwindcss'
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./app/**/*.{js,ts,jsx,tsx,mdx}'
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic':
|
||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: []
|
||||
}
|
||||
export default config
|
||||
22
packages/cli/test/fixtures/next-pages/tsconfig.json
vendored
Normal file
22
packages/cli/test/fixtures/next-pages/tsconfig.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"paths": {
|
||||
"~/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
304
packages/cli/test/utils/__snapshots__/css.test.ts.snap
Normal file
304
packages/cli/test/utils/__snapshots__/css.test.ts.snap
Normal file
@@ -0,0 +1,304 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`apply css updates 1`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
background-color: tomato;
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply css updates 2`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply css updates 3`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
--primary: 220.9 39.3% 11%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
--ring: 224 71.4% 4.1%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
--primary: 210 20% 98%;
|
||||
--primary-foreground: 220.9 39.3% 11%;
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
--ring: 216 12.2% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: tomato;
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply css updates 4`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
--primary: 220.9 39.3% 11%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
--ring: 224 71.4% 4.1%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
--primary: 210 20% 98%;
|
||||
--primary-foreground: 220.9 39.3% 11%;
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
--ring: 216 12.2% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply css updates 5`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
--primary: 220.9 39.3% 11%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
--ring: 224 71.4% 4.1%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
--primary: 210 20% 98%;
|
||||
--primary-foreground: 220.9 39.3% 11%;
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
--ring: 216 12.2% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply tw-border-border;
|
||||
}
|
||||
body {
|
||||
@apply tw-bg-background tw-text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: tomato;
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply css updates 6`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
--primary: 220.9 39.3% 11%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
--ring: 224 71.4% 4.1%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
--primary: 210 20% 98%;
|
||||
--primary-foreground: 220.9 39.3% 11%;
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
--ring: 216 12.2% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply cn-border-border;
|
||||
}
|
||||
body {
|
||||
@apply cn-bg-background cn-text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply css updates 7`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
background-color: tomato;
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply css updates 8`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
--primary: 220.9 39.3% 11%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
--ring: 224 71.4% 4.1%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
--primary: 210 20% 98%;
|
||||
--primary-foreground: 220.9 39.3% 11%;
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
--ring: 216 12.2% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: tomato;
|
||||
}
|
||||
"
|
||||
`;
|
||||
154
packages/cli/test/utils/css.test.ts
Normal file
154
packages/cli/test/utils/css.test.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
import { promises as fs } from "fs"
|
||||
import path from "path"
|
||||
import { expect, test } from "vitest"
|
||||
|
||||
import { applyCSSUpdates } from "../../src/utils/css"
|
||||
|
||||
const baseColor = {
|
||||
cssVars: {
|
||||
light: {
|
||||
background: "0 0% 100%",
|
||||
foreground: "224 71.4% 4.1%",
|
||||
primary: "220.9 39.3% 11%",
|
||||
"primary-foreground": "210 20% 98%",
|
||||
border: "220 13% 91%",
|
||||
input: "220 13% 91%",
|
||||
ring: "224 71.4% 4.1%",
|
||||
},
|
||||
dark: {
|
||||
background: "224 71.4% 4.1%",
|
||||
foreground: "210 20% 98%",
|
||||
primary: "210 20% 98%",
|
||||
"primary-foreground": "220.9 39.3% 11%",
|
||||
border: "215 27.9% 16.9%",
|
||||
input: "215 27.9% 16.9%",
|
||||
ring: "216 12.2% 83.9%",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
test("apply css updates", async () => {
|
||||
expect(
|
||||
await applyCSSUpdates(
|
||||
await fs.readFile(
|
||||
path.resolve(__dirname, "../fixtures/css/no-tailwind.css"),
|
||||
"utf8"
|
||||
),
|
||||
baseColor,
|
||||
{
|
||||
tailwind: {
|
||||
cssVariables: false,
|
||||
},
|
||||
}
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
|
||||
expect(
|
||||
await applyCSSUpdates(
|
||||
await fs.readFile(
|
||||
path.resolve(__dirname, "../fixtures/css/app-globals.css"),
|
||||
"utf8"
|
||||
),
|
||||
baseColor,
|
||||
{
|
||||
tailwind: {
|
||||
cssVariables: false,
|
||||
},
|
||||
}
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
|
||||
expect(
|
||||
await applyCSSUpdates(
|
||||
await fs.readFile(
|
||||
path.resolve(__dirname, "../fixtures/css/no-tailwind.css"),
|
||||
"utf8"
|
||||
),
|
||||
baseColor,
|
||||
{
|
||||
tailwind: {
|
||||
cssVariables: true,
|
||||
},
|
||||
}
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
|
||||
expect(
|
||||
await applyCSSUpdates(
|
||||
await fs.readFile(
|
||||
path.resolve(__dirname, "../fixtures/css/app-globals.css"),
|
||||
"utf8"
|
||||
),
|
||||
baseColor,
|
||||
{
|
||||
tailwind: {
|
||||
cssVariables: true,
|
||||
},
|
||||
}
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
|
||||
// Prefix.
|
||||
expect(
|
||||
await applyCSSUpdates(
|
||||
await fs.readFile(
|
||||
path.resolve(__dirname, "../fixtures/css/no-tailwind.css"),
|
||||
"utf8"
|
||||
),
|
||||
baseColor,
|
||||
{
|
||||
tailwind: {
|
||||
cssVariables: true,
|
||||
prefix: "tw-",
|
||||
},
|
||||
}
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
|
||||
expect(
|
||||
await applyCSSUpdates(
|
||||
await fs.readFile(
|
||||
path.resolve(__dirname, "../fixtures/css/app-globals.css"),
|
||||
"utf8"
|
||||
),
|
||||
baseColor,
|
||||
{
|
||||
tailwind: {
|
||||
cssVariables: true,
|
||||
prefix: "cn-",
|
||||
},
|
||||
}
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
|
||||
// Applied.
|
||||
expect(
|
||||
await applyCSSUpdates(
|
||||
await fs.readFile(
|
||||
path.resolve(__dirname, "../fixtures/css/applied.css"),
|
||||
"utf8"
|
||||
),
|
||||
baseColor,
|
||||
{
|
||||
tailwind: {
|
||||
cssVariables: false,
|
||||
},
|
||||
}
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
|
||||
expect(
|
||||
await applyCSSUpdates(
|
||||
await fs.readFile(
|
||||
path.resolve(__dirname, "../fixtures/css/applied-css-vars.css"),
|
||||
"utf8"
|
||||
),
|
||||
baseColor,
|
||||
{
|
||||
tailwind: {
|
||||
cssVariables: true,
|
||||
},
|
||||
}
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
})
|
||||
37
packages/cli/test/utils/get-project-type.test.ts
Normal file
37
packages/cli/test/utils/get-project-type.test.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import path from "path"
|
||||
import { describe, expect, test } from "vitest"
|
||||
|
||||
import { getProjectType } from "../../src/utils/get-project-info"
|
||||
|
||||
describe("get project type", async () => {
|
||||
test.each([
|
||||
{
|
||||
name: "next-app",
|
||||
type: "next-app",
|
||||
},
|
||||
{
|
||||
name: "next-app-src",
|
||||
type: "next-app-src",
|
||||
},
|
||||
{
|
||||
name: "next-pages",
|
||||
type: "next-pages",
|
||||
},
|
||||
{
|
||||
name: "next-pages-src",
|
||||
type: "next-pages-src",
|
||||
},
|
||||
{
|
||||
name: "project",
|
||||
type: null,
|
||||
},
|
||||
{
|
||||
name: "t3-app",
|
||||
type: "next-pages-src",
|
||||
},
|
||||
])(`getProjectType($name) -> $type`, async ({ name, type }) => {
|
||||
expect(
|
||||
await getProjectType(path.resolve(__dirname, `../fixtures/${name}`))
|
||||
).toBe(type)
|
||||
})
|
||||
})
|
||||
33
packages/cli/test/utils/get-tailwind-css-file.test.ts
Normal file
33
packages/cli/test/utils/get-tailwind-css-file.test.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import path from "path"
|
||||
import { describe, expect, test } from "vitest"
|
||||
|
||||
import { getTailwindCssFile } from "../../src/utils/get-project-info"
|
||||
|
||||
describe("get tailwind css file", async () => {
|
||||
test.each([
|
||||
{
|
||||
name: "next-app",
|
||||
file: "app/globals.css",
|
||||
},
|
||||
{
|
||||
name: "next-app-src",
|
||||
file: "src/app/styles.css",
|
||||
},
|
||||
{
|
||||
name: "next-pages",
|
||||
file: "styles/globals.css",
|
||||
},
|
||||
{
|
||||
name: "next-pages-src",
|
||||
file: "src/styles/globals.css",
|
||||
},
|
||||
{
|
||||
name: "t3-app",
|
||||
file: "src/styles/globals.css",
|
||||
},
|
||||
])(`getTailwindCssFile($name) -> $file`, async ({ name, file }) => {
|
||||
expect(
|
||||
await getTailwindCssFile(path.resolve(__dirname, `../fixtures/${name}`))
|
||||
).toBe(file)
|
||||
})
|
||||
})
|
||||
35
packages/cli/test/utils/get-ts-config-alias-prefix.test.ts
Normal file
35
packages/cli/test/utils/get-ts-config-alias-prefix.test.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import path from "path"
|
||||
import { describe, expect, test } from "vitest"
|
||||
|
||||
import { getTsConfigAliasPrefix } from "../../src/utils/get-project-info"
|
||||
|
||||
describe("get ts config alias prefix", async () => {
|
||||
test.each([
|
||||
{
|
||||
name: "next-app",
|
||||
prefix: "@",
|
||||
},
|
||||
{
|
||||
name: "next-app-src",
|
||||
prefix: "#",
|
||||
},
|
||||
{
|
||||
name: "next-pages",
|
||||
prefix: "~",
|
||||
},
|
||||
{
|
||||
name: "next-pages-src",
|
||||
prefix: "@",
|
||||
},
|
||||
{
|
||||
name: "t3-app",
|
||||
prefix: "~",
|
||||
},
|
||||
])(`getTsConfigAliasPrefix($name) -> $prefix`, async ({ name, prefix }) => {
|
||||
expect(
|
||||
await getTsConfigAliasPrefix(
|
||||
path.resolve(__dirname, `../fixtures/${name}`)
|
||||
)
|
||||
).toBe(prefix)
|
||||
})
|
||||
})
|
||||
37
packages/cli/test/utils/is-typescript-project.test.ts
Normal file
37
packages/cli/test/utils/is-typescript-project.test.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import path from "path"
|
||||
import { describe, expect, test } from "vitest"
|
||||
|
||||
import { isTypeScriptProject } from "../../src/utils/get-project-info"
|
||||
|
||||
describe("is TypeScript project", async () => {
|
||||
test.each([
|
||||
{
|
||||
name: "next-app",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "next-app-src",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "next-pages",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "next-pages-src",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "t3-app",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "next-app-js",
|
||||
result: false,
|
||||
},
|
||||
])(`isTypeScriptProject($name) -> $result`, async ({ name, result }) => {
|
||||
expect(
|
||||
await isTypeScriptProject(path.resolve(__dirname, `../fixtures/${name}`))
|
||||
).toBe(result)
|
||||
})
|
||||
})
|
||||
19
pnpm-lock.yaml
generated
19
pnpm-lock.yaml
generated
@@ -384,6 +384,9 @@ importers:
|
||||
execa:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0
|
||||
fast-glob:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
fs-extra:
|
||||
specifier: ^11.1.0
|
||||
version: 11.1.0
|
||||
@@ -4129,7 +4132,7 @@ packages:
|
||||
/@ts-morph/common@0.19.0:
|
||||
resolution: {integrity: sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==}
|
||||
dependencies:
|
||||
fast-glob: 3.3.0
|
||||
fast-glob: 3.3.2
|
||||
minimatch: 7.4.6
|
||||
mkdirp: 2.1.6
|
||||
path-browserify: 1.0.1
|
||||
@@ -6356,7 +6359,7 @@ packages:
|
||||
peerDependencies:
|
||||
tailwindcss: ^3.3.2
|
||||
dependencies:
|
||||
fast-glob: 3.2.12
|
||||
fast-glob: 3.3.0
|
||||
postcss: 8.4.24
|
||||
tailwindcss: 3.4.0(ts-node@10.9.1)
|
||||
dev: false
|
||||
@@ -6682,8 +6685,8 @@ packages:
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: false
|
||||
|
||||
/fast-glob@3.2.12:
|
||||
resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
|
||||
/fast-glob@3.3.0:
|
||||
resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
@@ -6692,8 +6695,8 @@ packages:
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.5
|
||||
|
||||
/fast-glob@3.3.0:
|
||||
resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==}
|
||||
/fast-glob@3.3.2:
|
||||
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
@@ -7022,7 +7025,7 @@ packages:
|
||||
dependencies:
|
||||
array-union: 2.1.0
|
||||
dir-glob: 3.0.1
|
||||
fast-glob: 3.3.0
|
||||
fast-glob: 3.3.2
|
||||
ignore: 5.2.4
|
||||
merge2: 1.4.1
|
||||
slash: 3.0.0
|
||||
@@ -10715,7 +10718,7 @@ packages:
|
||||
chokidar: 3.5.3
|
||||
didyoumean: 1.2.2
|
||||
dlv: 1.1.3
|
||||
fast-glob: 3.2.12
|
||||
fast-glob: 3.3.0
|
||||
glob-parent: 6.0.2
|
||||
is-glob: 4.0.3
|
||||
jiti: 1.18.2
|
||||
|
||||
Reference in New Issue
Block a user