mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-22 04:05:48 +00:00
Compare commits
12 Commits
shadcn@2.0
...
shadcn@2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd54184e60 | ||
|
|
ce3adfa075 | ||
|
|
674807c1b4 | ||
|
|
c62167a449 | ||
|
|
061083006f | ||
|
|
1af66c2d08 | ||
|
|
0993d98cc7 | ||
|
|
52d223393a | ||
|
|
207b69fe8d | ||
|
|
408760a93b | ||
|
|
a9ab7afebf | ||
|
|
b6221ea524 |
9
.github/workflows/issue-stale.yml
vendored
9
.github/workflows/issue-stale.yml
vendored
@@ -16,11 +16,12 @@ jobs:
|
|||||||
name: "Close stale issues with no reproduction"
|
name: "Close stale issues with no reproduction"
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.STALE_TOKEN }}
|
repo-token: ${{ secrets.STALE_TOKEN }}
|
||||||
close-issue-message: "This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you."
|
close-issue-message: "This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please reopen or leave a comment. Thank you.\n(This is an automated message.)"
|
||||||
days-before-issue-close: 7
|
days-before-issue-close: 7
|
||||||
days-before-issue-stale: 15
|
days-before-issue-stale: 30
|
||||||
stale-pr-label: "stale?"
|
stale-pr-label: "stale?"
|
||||||
days-before-pr-close: -1
|
days-before-pr-close: 7
|
||||||
days-before-pr-stale: -1
|
days-before-pr-stale: 15
|
||||||
|
only-pr-labels: "postpone: more info or changes requested,please add a reproduction"
|
||||||
exempt-issue-labels: "roadmap,next,bug"
|
exempt-issue-labels: "roadmap,next,bug"
|
||||||
operations-per-run: 300 # 1 operation per 100 issues, the rest is to label/comment/close
|
operations-per-run: 300 # 1 operation per 100 issues, the rest is to label/comment/close
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ links:
|
|||||||
|
|
||||||
Every data table or datagrid I've created has been unique. They all behave differently, have specific sorting and filtering requirements, and work with different data sources.
|
Every data table or datagrid I've created has been unique. They all behave differently, have specific sorting and filtering requirements, and work with different data sources.
|
||||||
|
|
||||||
It doesn't make sense to combine all of these variations into a single component. If we do that, we'll lose the flexibility that [headless UI](https://tanstack.com/table/v8/docs/guide/introduction#what-is-headless-ui) provides.
|
It doesn't make sense to combine all of these variations into a single component. If we do that, we'll lose the flexibility that [headless UI](https://tanstack.com/table/v8/docs/introduction#what-is-headless-ui) provides.
|
||||||
|
|
||||||
So instead of a data-table component, I thought it would be more helpful to provide a guide on how to build your own.
|
So instead of a data-table component, I thought it would be more helpful to provide a guide on how to build your own.
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ export default function RootLayout({ children }) {
|
|||||||
The `useToast` hook returns a `toast` function that you can use to display a toast.
|
The `useToast` hook returns a `toast` function that you can use to display a toast.
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { useToast } from "@/components/hooks/use-toast"
|
import { useToast } from "@/hooks/use-toast"
|
||||||
```
|
```
|
||||||
|
|
||||||
```tsx {2,7-10}
|
```tsx {2,7-10}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"files": [
|
"files": [
|
||||||
{
|
{
|
||||||
"path": "ui/input.tsx",
|
"path": "ui/input.tsx",
|
||||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input }\n",
|
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input }\n",
|
||||||
"type": "registry:ui",
|
"type": "registry:ui",
|
||||||
"target": ""
|
"target": ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"files": [
|
"files": [
|
||||||
{
|
{
|
||||||
"path": "ui/input.tsx",
|
"path": "ui/input.tsx",
|
||||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input }\n",
|
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input }\n",
|
||||||
"type": "registry:ui",
|
"type": "registry:ui",
|
||||||
"target": ""
|
"target": ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||||||
<input
|
<input
|
||||||
type={type}
|
type={type}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||||||
<input
|
<input
|
||||||
type={type}
|
type={type}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# @shadcn/ui
|
# @shadcn/ui
|
||||||
|
|
||||||
|
## 0.9.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#4797](https://github.com/shadcn-ui/ui/pull/4797) [`207b69f`](https://github.com/shadcn-ui/ui/commit/207b69fe8dd59b10dddc9337d333416976e2a30d) Thanks [@Wiper-R](https://github.com/Wiper-R)! - add scss support
|
||||||
|
|
||||||
## 0.9.0
|
## 0.9.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "shadcn-ui",
|
"name": "shadcn-ui",
|
||||||
"version": "0.9.0",
|
"version": "0.9.1",
|
||||||
"description": "Add components to your apps.",
|
"description": "Add components to your apps.",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export async function getProjectType(cwd: string): Promise<ProjectType | null> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getTailwindCssFile(cwd: string) {
|
export async function getTailwindCssFile(cwd: string) {
|
||||||
const files = await fg.glob("**/*.css", {
|
const files = await fg.glob(["**/*.css", "**/*.scss"], {
|
||||||
cwd,
|
cwd,
|
||||||
deep: 3,
|
deep: 3,
|
||||||
ignore: PROJECT_SHARED_IGNORE,
|
ignore: PROJECT_SHARED_IGNORE,
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
# @shadcn/ui
|
# @shadcn/ui
|
||||||
|
|
||||||
|
## 2.0.8
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#4922](https://github.com/shadcn-ui/ui/pull/4922) [`c62167a`](https://github.com/shadcn-ui/ui/commit/c62167a449a5cf82d8ed93a7af986d5e503893bb) Thanks [@sapenlei](https://github.com/sapenlei)! - remove next.js default vars
|
||||||
|
|
||||||
|
- [#4871](https://github.com/shadcn-ui/ui/pull/4871) [`ce3adfa`](https://github.com/shadcn-ui/ui/commit/ce3adfa075793a46b4fb2ff797ce87ad22bfa2cd) Thanks [@bcorbold](https://github.com/bcorbold)! - support tw prefixes for registry files with single quote formatting
|
||||||
|
|
||||||
|
## 2.0.7
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#4848](https://github.com/shadcn-ui/ui/pull/4848) [`1af66c2`](https://github.com/shadcn-ui/ui/commit/1af66c2d08df7dd7f6a8d4d1544d965e41a1fb0d) Thanks [@jherr](https://github.com/jherr)! - add support for ~ dir in target path
|
||||||
|
|
||||||
|
- [#4815](https://github.com/shadcn-ui/ui/pull/4815) [`408760a`](https://github.com/shadcn-ui/ui/commit/408760a93b398b7d02a0a522a74a7a195ccda7c4) Thanks [@rana-haris-ali](https://github.com/rana-haris-ali)! - fix typo in error message
|
||||||
|
|
||||||
## 2.0.6
|
## 2.0.6
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "shadcn",
|
"name": "shadcn",
|
||||||
"version": "2.0.6",
|
"version": "2.0.8",
|
||||||
"description": "Add components to your apps.",
|
"description": "Add components to your apps.",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export async function createProject(
|
|||||||
name: "proceed",
|
name: "proceed",
|
||||||
message: `The path ${highlighter.info(
|
message: `The path ${highlighter.info(
|
||||||
options.cwd
|
options.cwd
|
||||||
)} is does not contain a package.json file. Would you like to start a new ${highlighter.info(
|
)} does not contain a package.json file. Would you like to start a new ${highlighter.info(
|
||||||
"Next.js"
|
"Next.js"
|
||||||
)} project?`,
|
)} project?`,
|
||||||
initial: true,
|
initial: true,
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export async function getProjectInfo(cwd: string): Promise<ProjectInfo | null> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getTailwindCssFile(cwd: string) {
|
export async function getTailwindCssFile(cwd: string) {
|
||||||
const files = await fg.glob("**/*.css", {
|
const files = await fg.glob(["**/*.css", "**/*.scss"], {
|
||||||
cwd,
|
cwd,
|
||||||
deep: 5,
|
deep: 5,
|
||||||
ignore: PROJECT_SHARED_IGNORE,
|
ignore: PROJECT_SHARED_IGNORE,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const transformTwPrefixes: Transformer = async ({
|
|||||||
if (defaultClassNames) {
|
if (defaultClassNames) {
|
||||||
defaultClassNames.replaceWithText(
|
defaultClassNames.replaceWithText(
|
||||||
`"${applyPrefix(
|
`"${applyPrefix(
|
||||||
defaultClassNames.getText()?.replace(/"/g, ""),
|
defaultClassNames.getText()?.replace(/"|'/g, ""),
|
||||||
config.tailwind.prefix
|
config.tailwind.prefix
|
||||||
)}"`
|
)}"`
|
||||||
)
|
)
|
||||||
@@ -46,7 +46,7 @@ export const transformTwPrefixes: Transformer = async ({
|
|||||||
if (classNames) {
|
if (classNames) {
|
||||||
classNames?.replaceWithText(
|
classNames?.replaceWithText(
|
||||||
`"${applyPrefix(
|
`"${applyPrefix(
|
||||||
classNames.getText()?.replace(/"/g, ""),
|
classNames.getText()?.replace(/"|'/g, ""),
|
||||||
config.tailwind.prefix
|
config.tailwind.prefix
|
||||||
)}"`
|
)}"`
|
||||||
)
|
)
|
||||||
@@ -65,7 +65,7 @@ export const transformTwPrefixes: Transformer = async ({
|
|||||||
if (value) {
|
if (value) {
|
||||||
value.replaceWithText(
|
value.replaceWithText(
|
||||||
`"${applyPrefix(
|
`"${applyPrefix(
|
||||||
value.getText()?.replace(/"/g, ""),
|
value.getText()?.replace(/"|'/g, ""),
|
||||||
config.tailwind.prefix
|
config.tailwind.prefix
|
||||||
)}"`
|
)}"`
|
||||||
)
|
)
|
||||||
@@ -91,7 +91,7 @@ export const transformTwPrefixes: Transformer = async ({
|
|||||||
.forEach((node) => {
|
.forEach((node) => {
|
||||||
node.replaceWithText(
|
node.replaceWithText(
|
||||||
`"${applyPrefix(
|
`"${applyPrefix(
|
||||||
node.getText()?.replace(/"/g, ""),
|
node.getText()?.replace(/"|'/g, ""),
|
||||||
config.tailwind.prefix
|
config.tailwind.prefix
|
||||||
)}"`
|
)}"`
|
||||||
)
|
)
|
||||||
@@ -101,7 +101,7 @@ export const transformTwPrefixes: Transformer = async ({
|
|||||||
if (node.isKind(SyntaxKind.StringLiteral)) {
|
if (node.isKind(SyntaxKind.StringLiteral)) {
|
||||||
node.replaceWithText(
|
node.replaceWithText(
|
||||||
`"${applyPrefix(
|
`"${applyPrefix(
|
||||||
node.getText()?.replace(/"/g, ""),
|
node.getText()?.replace(/"|'/g, ""),
|
||||||
config.tailwind.prefix
|
config.tailwind.prefix
|
||||||
)}"`
|
)}"`
|
||||||
)
|
)
|
||||||
@@ -130,7 +130,7 @@ export const transformTwPrefixes: Transformer = async ({
|
|||||||
.forEach((node) => {
|
.forEach((node) => {
|
||||||
node.replaceWithText(
|
node.replaceWithText(
|
||||||
`"${applyPrefix(
|
`"${applyPrefix(
|
||||||
node.getText()?.replace(/"/g, ""),
|
node.getText()?.replace(/"|'/g, ""),
|
||||||
config.tailwind.prefix
|
config.tailwind.prefix
|
||||||
)}"`
|
)}"`
|
||||||
)
|
)
|
||||||
@@ -140,7 +140,7 @@ export const transformTwPrefixes: Transformer = async ({
|
|||||||
if (arg.isKind(SyntaxKind.StringLiteral)) {
|
if (arg.isKind(SyntaxKind.StringLiteral)) {
|
||||||
arg.replaceWithText(
|
arg.replaceWithText(
|
||||||
`"${applyPrefix(
|
`"${applyPrefix(
|
||||||
arg.getText()?.replace(/"/g, ""),
|
arg.getText()?.replace(/"|'/g, ""),
|
||||||
config.tailwind.prefix
|
config.tailwind.prefix
|
||||||
)}"`
|
)}"`
|
||||||
)
|
)
|
||||||
@@ -155,7 +155,7 @@ export const transformTwPrefixes: Transformer = async ({
|
|||||||
if (classNames) {
|
if (classNames) {
|
||||||
classNames.replaceWithText(
|
classNames.replaceWithText(
|
||||||
`"${applyPrefix(
|
`"${applyPrefix(
|
||||||
classNames.getText()?.replace(/"/g, ""),
|
classNames.getText()?.replace(/"|'/g, ""),
|
||||||
config.tailwind.prefix
|
config.tailwind.prefix
|
||||||
)}"`
|
)}"`
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -183,6 +183,27 @@ function updateCssVarsPlugin(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeConflictVars(root: Rule | Root) {
|
||||||
|
const rootRule = root.nodes.find(
|
||||||
|
(node): node is Rule => node.type === "rule" && node.selector === ":root"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (rootRule) {
|
||||||
|
const propsToRemove = ["--background", "--foreground"]
|
||||||
|
|
||||||
|
rootRule.nodes
|
||||||
|
.filter(
|
||||||
|
(node): node is postcss.Declaration =>
|
||||||
|
node.type === "decl" && propsToRemove.includes(node.prop)
|
||||||
|
)
|
||||||
|
.forEach((node) => node.remove())
|
||||||
|
|
||||||
|
if (rootRule.nodes.length === 0) {
|
||||||
|
rootRule.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function cleanupDefaultNextStylesPlugin() {
|
function cleanupDefaultNextStylesPlugin() {
|
||||||
return {
|
return {
|
||||||
postcssPlugin: "cleanup-default-next-styles",
|
postcssPlugin: "cleanup-default-next-styles",
|
||||||
@@ -197,7 +218,9 @@ function cleanupDefaultNextStylesPlugin() {
|
|||||||
(node): node is postcss.Declaration =>
|
(node): node is postcss.Declaration =>
|
||||||
node.type === "decl" &&
|
node.type === "decl" &&
|
||||||
node.prop === "color" &&
|
node.prop === "color" &&
|
||||||
node.value === "rgb(var(--foreground-rgb))"
|
["rgb(var(--foreground-rgb))", "var(--foreground)"].includes(
|
||||||
|
node.value
|
||||||
|
)
|
||||||
)
|
)
|
||||||
?.remove()
|
?.remove()
|
||||||
|
|
||||||
@@ -208,7 +231,8 @@ function cleanupDefaultNextStylesPlugin() {
|
|||||||
node.type === "decl" &&
|
node.type === "decl" &&
|
||||||
node.prop === "background" &&
|
node.prop === "background" &&
|
||||||
// This is only going to run on create project, so all good.
|
// This is only going to run on create project, so all good.
|
||||||
node.value.startsWith("linear-gradient")
|
(node.value.startsWith("linear-gradient") ||
|
||||||
|
node.value === "var(--background)")
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
?.remove()
|
?.remove()
|
||||||
@@ -218,6 +242,21 @@ function cleanupDefaultNextStylesPlugin() {
|
|||||||
bodyRule.remove()
|
bodyRule.remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeConflictVars(root)
|
||||||
|
|
||||||
|
const darkRootRule = root.nodes.find(
|
||||||
|
(node): node is Rule =>
|
||||||
|
node.type === "atrule" &&
|
||||||
|
node.params === "(prefers-color-scheme: dark)"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (darkRootRule) {
|
||||||
|
removeConflictVars(darkRootRule)
|
||||||
|
if (darkRootRule.nodes.length === 0) {
|
||||||
|
darkRootRule.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,19 @@ import { transformRsc } from "@/src/utils/transformers/transform-rsc"
|
|||||||
import { transformTwPrefixes } from "@/src/utils/transformers/transform-tw-prefix"
|
import { transformTwPrefixes } from "@/src/utils/transformers/transform-tw-prefix"
|
||||||
import prompts from "prompts"
|
import prompts from "prompts"
|
||||||
|
|
||||||
|
export function resolveTargetDir(
|
||||||
|
projectInfo: Awaited<ReturnType<typeof getProjectInfo>>,
|
||||||
|
config: Config,
|
||||||
|
target: string
|
||||||
|
) {
|
||||||
|
if (target.startsWith("~/")) {
|
||||||
|
return path.join(config.resolvedPaths.cwd, target.replace("~/", ""))
|
||||||
|
}
|
||||||
|
return projectInfo?.isSrcDir
|
||||||
|
? path.join(config.resolvedPaths.cwd, "src", target)
|
||||||
|
: path.join(config.resolvedPaths.cwd, target)
|
||||||
|
}
|
||||||
|
|
||||||
export async function updateFiles(
|
export async function updateFiles(
|
||||||
files: RegistryItem["files"],
|
files: RegistryItem["files"],
|
||||||
config: Config,
|
config: Config,
|
||||||
@@ -58,9 +71,7 @@ export async function updateFiles(
|
|||||||
let filePath = path.join(targetDir, fileName)
|
let filePath = path.join(targetDir, fileName)
|
||||||
|
|
||||||
if (file.target) {
|
if (file.target) {
|
||||||
filePath = projectInfo?.isSrcDir
|
filePath = resolveTargetDir(projectInfo, config, file.target)
|
||||||
? path.join(config.resolvedPaths.cwd, "src", file.target)
|
|
||||||
: path.join(config.resolvedPaths.cwd, file.target)
|
|
||||||
targetDir = path.dirname(filePath)
|
targetDir = path.dirname(filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,14 @@ export function Foo() {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`transform tailwind prefix 4`] = `
|
exports[`transform tailwind prefix 4`] = `
|
||||||
|
"import * as React from "react"
|
||||||
|
export function Foo() {
|
||||||
|
return <div className={cn("tw-bg-background hover:tw-bg-muted", true && "tw-text-primary-foreground sm:focus:tw-text-accent-foreground")}>foo</div>
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`transform tailwind prefix 5`] = `
|
||||||
"@tailwind base;
|
"@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||||||
<input
|
<input
|
||||||
type={type}
|
type={type}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -73,6 +73,29 @@ export function Foo() {
|
|||||||
})
|
})
|
||||||
).toMatchSnapshot()
|
).toMatchSnapshot()
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await transform({
|
||||||
|
filename: "test.ts",
|
||||||
|
raw: `import * as React from "react"
|
||||||
|
export function Foo() {
|
||||||
|
return <div className={cn('bg-background hover:bg-muted', true && 'text-primary-foreground sm:focus:text-accent-foreground')}>foo</div>
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
config: {
|
||||||
|
tailwind: {
|
||||||
|
baseColor: "stone",
|
||||||
|
cssVariables: false,
|
||||||
|
prefix: "tw-",
|
||||||
|
},
|
||||||
|
aliases: {
|
||||||
|
components: "@/components",
|
||||||
|
utils: "@/lib/utils",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
baseColor: stone,
|
||||||
|
})
|
||||||
|
).toMatchSnapshot()
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
applyPrefixesCss(
|
applyPrefixesCss(
|
||||||
"@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n \n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n \n --border: 220 13% 91%;\n --input: 220 13% 91%;\n \n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n \n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n \n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 217.9 10.6% 64.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n \n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n \n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n \n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n \n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n \n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n \n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n \n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 215 27.9% 16.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}",
|
"@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n \n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n \n --border: 220 13% 91%;\n --input: 220 13% 91%;\n \n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n \n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n \n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 217.9 10.6% 64.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n \n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n \n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n \n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n \n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n \n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n \n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n \n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 215 27.9% 16.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}",
|
||||||
|
|||||||
65
packages/shadcn/test/utils/updaters/update-files.test.ts
Normal file
65
packages/shadcn/test/utils/updaters/update-files.test.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { describe, expect, test } from "vitest"
|
||||||
|
|
||||||
|
import { resolveTargetDir } from "../../../src/utils/updaters/update-files"
|
||||||
|
|
||||||
|
describe("resolveTargetDir", () => {
|
||||||
|
test("should handle a home target without a src directory", () => {
|
||||||
|
const targetDir = resolveTargetDir(
|
||||||
|
{
|
||||||
|
isSrcDir: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolvedPaths: {
|
||||||
|
cwd: "/foo/bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"~/.env"
|
||||||
|
)
|
||||||
|
expect(targetDir).toBe("/foo/bar/.env")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should handle a home target even with a src directory", () => {
|
||||||
|
const targetDir = resolveTargetDir(
|
||||||
|
{
|
||||||
|
isSrcDir: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolvedPaths: {
|
||||||
|
cwd: "/foo/bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"~/.env"
|
||||||
|
)
|
||||||
|
expect(targetDir).toBe("/foo/bar/.env")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should handle a simple target", () => {
|
||||||
|
const targetDir = resolveTargetDir(
|
||||||
|
{
|
||||||
|
isSrcDir: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolvedPaths: {
|
||||||
|
cwd: "/foo/bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"./components/ui/button.tsx"
|
||||||
|
)
|
||||||
|
expect(targetDir).toBe("/foo/bar/components/ui/button.tsx")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should handle a simple target with src directory", () => {
|
||||||
|
const targetDir = resolveTargetDir(
|
||||||
|
{
|
||||||
|
isSrcDir: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolvedPaths: {
|
||||||
|
cwd: "/foo/bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"./components/ui/button.tsx"
|
||||||
|
)
|
||||||
|
expect(targetDir).toBe("/foo/bar/src/components/ui/button.tsx")
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user