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

✨ Support Angular #85

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ export default config;
| React | ✅ |
| Vue | 🚧 |
| Lit | ✅ |
| Angular | 🚧 |
| Angular | |
| Svelte | 📝 |
| Custom | 📝 |
4 changes: 4 additions & 0 deletions asg.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
"name": "🧪 svelte",
"path": "playgrounds/svelte",
},
{
"name": "🧪 angular",
"path": "playgrounds/angular",
},
],
"settings": {
"prettier.enable": false,
Expand Down
35 changes: 32 additions & 3 deletions docs/useCase/angular.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Svelte
# Angular

::: warning
🚧 Currently working on a response....
:::
📝 Not a fully functioning story generation...
:::

### Setup

`.storybook/main.ts` or `.storybook/main.js`
::: code-group

```ts [Webpack]
autoStoryGenerator.webpack({
preset: "angular",

// depending on your folder structure set imports array
// "src/**/components/**/*.ts"; or "src/**/*.ts";
imports: ["src/components/**/*.ts"],
})
```
:::

<!-- ### Example (Case 1)



::: code-group
```ts [component]

```

```ts [story]
```
::: -->
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"pg:angular": "pnpm -C playgrounds/angular",
"pg:lit": "pnpm -C playgrounds/lit"
},
"author": "takuma-ru <[email protected]> (https://github.com/takuma-ru/)",
"author": "takuma-ru <[email protected]> (https://github.com/takuma-ru/)",
"license": "ISC",
"packageManager": "[email protected]",
"engines": {
Expand Down
6 changes: 5 additions & 1 deletion packages/auto-story-generator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ export default config;
| Custom | 📝 |

## Contributors

### Main contributor
[![](https://avatars.githubusercontent.com/u/49429291?v=4&size=32)](https://github.com/takuma-ru)

[![](https://avatars.githubusercontent.com/u/49429291?v=4&size=32)](https://github.com/takuma-ru)<br>

takuma-ru : Core API, React presets more...

### Special thanks

<!-- TODO: Add GeetaKrishna65 Profile image -->
<!-- GeetaKrishna65 : Create Angular presets -->
13 changes: 11 additions & 2 deletions packages/auto-story-generator/src/core/genStoryFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { minimatch } from "minimatch";
import * as prettier from "prettier";
import { Project, SyntaxKind } from "ts-morph";
import { getComponentInfo } from "~/src/core/getComponentInfo";
import { genAngularStoryFile } from "~/src/presets/angular/genAngularStoryFile";
import { genLitStoryFile } from "~/src/presets/lit/genLitStoryFile";
import { genReactStoryFile } from "~/src/presets/react/genReactStoryFile";
import { throwErr } from "~/src/utils/throwError";
Expand Down Expand Up @@ -118,8 +119,16 @@ export async function genStoryFile({
}

case "angular": {
throwErr({
errorCode: "EC01",
genStoryFileOptions = await genAngularStoryFile({
componentName,
fileBase,
fileName,
path: id,
fileExt,
filePrefixExt,
relativeSourceFilePath,
sourceFile,
prettierConfigPath: options.prettierConfigPath,
});

break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import type { GenStoryFileOptions } from "~/src/types/GenStoryFileType";

import { pascalCase } from "scule";

export const genAngularStoryFile = async ({
componentName,
fileBase,
fileName,
filePrefixExt,
path,
fileExt,
relativeSourceFilePath,
sourceFile,
prettierConfigPath,
}: GenStoryFileOptions["fileOptions"]): Promise<
GenStoryFileOptions | undefined
> => {
// const { propTypes } =
// getAngularPropTypes({
// sourceFile,
// componentName,
// });
const pascalComponentName = pascalCase(`${componentName}Component`);
// if (!propTypes) return consola.error("Could not find argTypes");

// Angular doesn't need file with extension
const file = fileName.split(".");
file.pop();

const initialCode = `
import type { Meta, StoryObj } from "@storybook/angular";

import { ${pascalComponentName} } from "./${file.join(".")}";

const meta: Meta<${pascalComponentName}> = {
title: "components/${pascalComponentName}",
component: ${pascalComponentName},
tags: ["autodocs"],
render: (args: ${pascalComponentName}) => ({
props: {
...args
}
})
};

export default meta;
type Story = StoryObj<${pascalComponentName}>;

export const Primary: Story = {};
`;

const _componentCode = `${pascalComponentName}`;

// const args: GenStoryFileOptions["generateOptions"]["meta"]["args"] = {};

// propTypes.forEach((prop) => {
// if (prop.isOptional) {
// return (args[prop.name] = "undefined");
// }

// let value: string | boolean | undefined =
// prop.value.length > 0 ? prop.value[0] : "undefined";

// if (prop.type.includes("boolean")) {
// value = true;
// }

// args[prop.name] = value;
// });

// const argTypes: GenStoryFileOptions["generateOptions"]["meta"]["argTypes"] =
// {};

// propTypes.forEach((prop) => {
// if (prop.type[0] === "boolean") {
// return (argTypes[prop.name] = {
// control: "boolean",
// });
// }

// if (prop.type[0] === "object") {
// return (argTypes[prop.name] = {
// control: "object",
// });
// }

// if (prop.value.length > 1) {
// return (argTypes[prop.name] = {
// control: "select",
// options: prop.value,
// });
// } else {
// if (prop.type[0] === "string") {
// return (argTypes[prop.name] = {
// control: "text",
// });
// }

// if (prop.type[0] === "number") {
// return (argTypes[prop.name] = {
// control: "number",
// });
// }
// }
// });

return {
fileOptions: {
componentName,
fileBase,
fileName,
filePrefixExt,
path,
fileExt,
relativeSourceFilePath,
sourceFile,
prettierConfigPath,
},
generateOptions: {
fileExt: ".stories.ts",
initialCode,
meta: {
// component: componentCode,
},
},
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import type { SourceFile } from "ts-morph";
import { pascalCase } from "scule";

// const getTypeFlagsName = (flags: TypeFlags) => {
// // Get all the keys of TypeFlags
// const keys = Object.keys(TypeFlags) as (keyof typeof TypeFlags)[];

// // Filter the keys where the flag is set
// const setFlags = keys.find(key => flags === TypeFlags[key]);

// return setFlags || "err";
// };

// Didn't understnd the Props yet, will add this after proper understanding is reached.
export const getAngularPropTypes = ({ sourceFile: _sourceFile, componentName }: { sourceFile: SourceFile; componentName: string }) => {
const _pascalComponentName = pascalCase(componentName);
};

// export const getAngularPropTypes = ({
// sourceFile,
// componentName,
// }: GenReactPropTypesOptions): {
// propsPattern?: "component-props" | "props" | "inline";
// propTypes: GenReactPropTypesReturn;
// } => {
// let propsPattern: "component-props" | "props" | "inline" = "component-props";

// const props =
// propsType?.getType() ||
// propsInterface?.getType() ||
// propsOnlyType?.getType() ||
// propsOnlyInterface?.getType() ||
// propsInline?.getParameters()[0].getType();

// if (!props) {
// return {
// propTypes: undefined,
// };
// }

// // eslint-disable-next-line @typescript-eslint/ban-types
// let propsProperties: Symbol[] = [];
// const isPropsIntersection = props.isIntersection();
// if (isPropsIntersection) {
// propsProperties = [];

// const intersectionTypes = props.getIntersectionTypes();

// intersectionTypes.forEach((intersectionType) => {
// const intersectionTypeText = intersectionType.getText();

// if (intersectionTypeText.includes("HTMLAttributes")) {
// return;
// }

// return propsProperties.push(...intersectionType.getProperties());
// });
// } else {
// propsProperties = props.getProperties();
// }

// if (propsOnlyType || propsOnlyInterface) {
// propsPattern = "props";
// }

// if (propsInline) {
// propsPattern = "inline";
// }

// const propTypes = propsProperties.map((prop) => {
// const propName = prop.getName();
// const propType = prop.getValueDeclaration()?.getType();

// if (!propType) {
// return {
// name: propName,
// type: ["err"],
// isOptional: prop.isOptional(),
// value: [],
// };
// }

// if (propType.isUnion() && !propType.isBoolean()) {
// const unionTypes = propType.getUnionTypes();

// const type = Array.from(
// new Set(
// unionTypes.map((union) =>
// getTypeFlagsName(union.getFlags().valueOf()),
// ),
// ),
// );

// return {
// name: propName,
// type,
// isOptional: prop.isOptional(),
// value: unionTypes.map((union) => union.getText().replace(/"/g, "")),
// };
// }

// return {
// name: propName,
// type: [prop.getValueDeclaration()!.getType().getText()],
// isOptional: prop.isOptional(),
// value: [],
// };
// });

// return {
// propsPattern,
// propTypes,
// };
// };
16 changes: 16 additions & 0 deletions playgrounds/angular/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.ts]
quote_type = single

[*.md]
max_line_length = off
trim_trailing_whitespace = false
Loading
Loading