-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
feat(cli): add config option to capitalize component filenames #774
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(cli): add config option to capitalize component filenames #774
Conversation
filenames are not capitalized when overwriting
@plbstl is attempting to deploy a commit to the shadcn-pro Team on Vercel. A member of the Team first needs to authorize it. |
I agree, I always capitalize my components, and I know many people also do. I would love it if this feature was implemented! |
I think that we would get too many prompts in the |
I agree with you. This implementation does not modify the init command and allows the new config option to be optional.
Yes. #773 |
I definitely want to support casing for file names. I'll label this and get back to it. I'll think about the best to implement this so that we can support any naming convention. Thanks for starting the work on this @plbstl |
Dropping this here as a temporary workaround. Usagenpm run add-component button
# will install the button component and rename file from button.tsx to Button.tsx Installationnpm i -D tsx @types/node // File: package.json
scripts: {
// ...
"add-component": "tsx ./npm-scripts/add-component.ts"
// ...
} // File: npm-scripts/add-component.ts
import { exec } from 'node:child_process'
import { rename } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = import.meta.dirname ?? dirname(fileURLToPath(import.meta.url))
// modify this to match the path of your ui components folder (relative to this file)
const base = resolve(__dirname, '..', 'src', 'components', 'ui')
main()
function main() {
const componentName = process.argv[2]
if (!componentName) {
console.error('Please provide a component name.')
} else {
createComponent(componentName)
}
}
function createComponent(componentName: string) {
const command = `npx shadcn-ui@latest add ${componentName}`
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`Error executing command: ${error.message}`)
return
}
if (stdout) console.log(`${stdout}`)
if (stderr) console.log(`${stderr}`)
const oldFilePath = resolve(base, `${componentName}.tsx`)
const newFilePath = resolve(base, `${renamer(componentName)}.tsx`)
renameFile(oldFilePath, newFilePath)
})
}
function renamer(name: string) {
// change from kebab-case to PascalCase
return name
.split('-')
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
.join('')
}
function renameFile(oldPath: string, newPath: string) {
rename(oldPath, newPath, err => {
if (err) {
console.error(`Error renaming file: ${err}`)
return
}
console.log(`File renamed to ${newPath}`)
})
} |
Just started incorporating shadcn recently and I'd advice a bit of care with @atej's solution, as I found cross dependencies between some components, which would remain with invalid filenames on import. They are easily fixable but it should be taken into consideration. One example of this happening is with the Alert Dialog component, which requires // src/components/alert-dialog
"use client"
import * as React from "react"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
... 👍 +1 to having a config option for this |
Hello, I've created #2723. |
Can someone please review and merge this PR? |
Here is updated version of @atej workaround with using // // File: npm-scripts/add-component.ts
import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
function pascalCase(str: string): string {
return str.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
}
function addComponent(componentName: string): void {
try {
// Run the shadcn command
console.log(`Adding component: ${componentName}`);
execSync(`npx shadcn@latest add ${componentName}`, { stdio: 'inherit' });
// Rename the generated file
// Update uiDir based on your project structure
const uiDir = path.join(process.cwd(), 'components', 'ui');
const oldPath = path.join(uiDir, `${componentName}.tsx`);
const newPath = path.join(uiDir, `${pascalCase(componentName)}.tsx`);
if (fs.existsSync(oldPath)) {
fs.renameSync(oldPath, newPath);
console.log(`Renamed ${componentName}.tsx to ${pascalCase(componentName)}.tsx`);
} else {
console.warn(`Warning: ${componentName}.tsx not found in components/ui directory`);
}
} catch (error) {
console.error('Error adding component:', error);
}
}
// Get the component name from command-line arguments
const componentName = process.argv[2];
if (!componentName) {
console.error('Please provide a component name');
process.exit(1);
}
addComponent(componentName); |
+1 For this. Choosing a naming convention is important |
filenames are not capitalized when overwriting
See #748