Skip to content
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

CLI command for initializing component boilerplate #109

Merged
merged 8 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Feature: GitHub source links for components via [@etchteam/storybook-addon-github-link](https://storybook.js.org/addons/@etchteam/storybook-addon-github-link) in storybook docs
- Patch: Update method of declaring Storybook component descriptions and add import instructions to components
- Patch: Remove description field from top level `meta` object in component `.stories.svelte` files (do not render)
- Feature: CLI command to generate new component boilerplate (`npm run create-component`)

## v0.10.2

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ To build your library:
npm run package
```

### CLI-based command for creating new component boilerplate

To create three boilerplate files for a new component (`ComponentName.svelte`, `ComponentName.stories.svelte`, and `ComponentName.docs.md`), run the following command:

```bash
npm run create-component
```

## Contributing to this library

When contributing to this library, keep the following guidelines in mind. The [pull request template](https://github.com/UrbanInstitute/dataviz-components/blob/main/.github/pull_request_template.md) requires explanation of changes and provides a checklist of tasks to ensure clean code and documentation. Please name all branches in `kebab-case`, beginning with "patch", "feature", or "bugfix", and provide insightful commit messages.
61 changes: 61 additions & 0 deletions bin/createComponent/createComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env node
import inquirer from "inquirer";
import fs from "fs";
import path from "path";
import { createStory } from "./createStory.js";
import { createDocs } from "./createDocs.js";

// check if PascalCase https://www.w3resource.com/javascript-exercises/javascript-string-exercise-56.php
function isPascalCase(str) {
return /^[A-Z][A-Za-z]*$/.test(str);
}

async function main() {
await inquirer
.prompt([
{
type: "input",
name: "componentName",
message: "What is the name of your component? (ie: MyComponent)",
validate: (componentName) => {
// if not present
if (!componentName) {
return "Please enter a component name";
// if not PascalCase
} else if (!isPascalCase(componentName)) {
return "Component name must be in PascalCase";
} else {
return true;
}
}
}
])
.then((answers) => {
const { componentName } = answers;
const dir = path.join(process.cwd(), "src", "lib", componentName);
// if directory doesn't exist, create it
if (!fs.existsSync(dir)) {
// create directory
fs.mkdirSync(dir, { recursive: true });

// create Component.svelte (blank)
const svelteFilePath = path.join(dir, `${componentName}.svelte`);
fs.writeFileSync(svelteFilePath, "", "utf8");

// create Component.docs.md
const docsFilePath = path.join(dir, `${componentName}.docs.md`);
fs.writeFileSync(docsFilePath, createDocs(componentName), "utf8");

// create Component.stories.svelte
const storyFilePath = path.join(dir, `${componentName}.stories.svelte`);
fs.writeFileSync(storyFilePath, createStory(componentName), "utf8");

// Confirmation text
console.log(`Boilerplate files created in ${dir}`);
} else {
console.error("Directory already exists");
}
});
}

main().catch(console.error);
9 changes: 9 additions & 0 deletions bin/createComponent/createDocs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function createDocs(componentName) {
return `
Esse ipsum deserunt dolor minim dolore sunt cillum.

\`\`\`js
import { ${componentName} } from "@urbaninstitute/dataviz-components";
\`\`\`
`;
}
35 changes: 35 additions & 0 deletions bin/createComponent/createStory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export function createStory(componentName) {
return `
<script context="module">
import ${componentName} from "./${componentName}.svelte";
import docs from "./${componentName}.docs.md?raw";

export const meta = {
title: "Components/${componentName}",
component: ${componentName},
tags: ["autodocs"],
parameters: {
docs: {
description: {
component: docs
}
},
githubLink: {
url: "/${componentName}/${componentName}.svelte"
}
}
};
</script>

<script>
import { Story, Template } from "@storybook/addon-svelte-csf";
</script>

<Template let:args>
<${componentName} {...args} />
</Template>

<Story
name="Default"
/>`;
}
Loading