diff --git a/.scaffdog/documents/component.md b/.scaffdog/documents/component.md
index 2e1093d..a4246bb 100644
--- a/.scaffdog/documents/component.md
+++ b/.scaffdog/documents/component.md
@@ -4,12 +4,51 @@ root: "."
output: "**/*"
---
-# [[inputs.name]].[[inputs.authoringFormat]]
+# [[inputs.authoringFormat == "gjs" ? (inputs.classBased ? "!" : "") : "!"]][[inputs.name]].gjs
+
+```gjs
+{{yield}}
+
+```
+
+# [[inputs.authoringFormat == "gjs" ? (inputs.classBased ? "" : "!") : "!"]][[inputs.name]].gjs
+
+```gjs
+[[name := pascal(inputs.name)-]]
+import Component from "@glimmer/component";
+
+export default class [[name]] extends Component {
+ {{yield}}
+}
+
+```
+
+# [[inputs.authoringFormat == "gts" ? (inputs.classBased ? "!" : "") : "!"]][[inputs.name]].gts
+
+```gts
+[[name := pascal(inputs.name)-]]
+import type { TOC } from '@ember/component/template-only';
+
+export interface [[name]]Signature {
+ Args: {};
+ Blocks: {
+ default: [];
+ };
+ Element: null;
+}
+
+const [[name]]: TOC<[[name]]Signature> = {{yield}};
+
+export default [[name]];
+
+```
+
+# [[inputs.authoringFormat == "gts" ? (inputs.classBased ? "" : "!") : "!"]][[inputs.name]].gts
```gts
[[name := pascal(inputs.name)-]]
import Component from "@glimmer/component";
-[[if inputs.authoringFormat == "gts"]]
+
export interface [[name]]Signature {
Args: {};
Blocks: {
@@ -18,10 +57,7 @@ export interface [[name]]Signature {
Element: null;
}
-export default class [[name]]Component extends Component<[[name]]Signature> {
-[[-else]]
-export default class [[name]]Component extends Component {
-[[-end]]
+export default class [[name]] extends Component<[[name]]Signature> {
{{yield}}
diff --git a/README.md b/README.md
index 560bd45..bb5455d 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,7 @@ yarn add -D @bertdeblock/gember
```shell
pnpm gember component foo
+pnpm gember component foo --class
pnpm gember component foo --gts
pnpm gember component foo --path="src/-private"
@@ -45,6 +46,6 @@ pnpm gember service foo --ts
pnpm gember service foo --path="src/-private"
```
-## Caveats
+## Notes
-- Only supports `.gjs` (default) and `.gts` files for components at the moment
+- Only supports `.gjs` (default) and `.gts` files for components
diff --git a/src/cli.ts b/src/cli.ts
index b852cf4..316872a 100644
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -19,6 +19,12 @@ yargs(hideBin(process.argv))
description: "The component's name",
type: "string",
})
+ .option("class-based", {
+ alias: ["class"],
+ default: false,
+ description: "Generate a class-based component",
+ type: "boolean",
+ })
.option("gts", {
default: false,
description: "Generate a `.gts` component",
@@ -33,6 +39,7 @@ yargs(hideBin(process.argv))
handler(options) {
generateComponent(options.name, {
authoringFormat: options.gts ? "gts" : "gjs",
+ classBased: options.classBased,
path: options.path,
});
},
diff --git a/src/generators.ts b/src/generators.ts
index 3cd67d6..6110ded 100644
--- a/src/generators.ts
+++ b/src/generators.ts
@@ -5,17 +5,19 @@ export function generateComponent(
name: string,
{
authoringFormat = "gjs",
+ classBased = false,
cwd = "",
path = "",
}: {
authoringFormat?: "gjs" | "gts";
+ classBased?: boolean;
cwd?: string;
path?: string;
} = {},
) {
return generateDocument(DocumentName.Component, name, {
cwd,
- inputs: { authoringFormat },
+ inputs: { authoringFormat, classBased },
path,
});
}
diff --git a/test/__snapshots__/generate-component.test.ts.snap b/test/__snapshots__/generate-component.test.ts.snap
index 898506a..46e5306 100644
--- a/test/__snapshots__/generate-component.test.ts.snap
+++ b/test/__snapshots__/generate-component.test.ts.snap
@@ -1,28 +1,25 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`generates a \`.gjs\` component 1`] = `
+exports[`generates a \`.gjs\` class-based component 1`] = `
"import Component from "@glimmer/component";
-export default class FooComponent extends Component {
-
- {{yield}}
-
+export default class Foo extends Component {
+ {{yield}}
}
"
`;
-exports[`generates a \`.gjs\` component at a custom path 1`] = `
-"import Component from "@glimmer/component";
+exports[`generates a \`.gjs\` template-only component 1`] = `
+"{{yield}}
+"
+`;
-export default class FooComponent extends Component {
-
- {{yield}}
-
-}
+exports[`generates a \`.gjs\` template-only component at a custom path 1`] = `
+"{{yield}}
"
`;
-exports[`generates a \`.gts\` component 1`] = `
+exports[`generates a \`.gts\` class-based component 1`] = `
"import Component from "@glimmer/component";
export interface FooSignature {
@@ -33,7 +30,7 @@ export interface FooSignature {
Element: null;
}
-export default class FooComponent extends Component {
+export default class Foo extends Component {
{{yield}}
@@ -41,8 +38,8 @@ export default class FooComponent extends Component {
"
`;
-exports[`generates a \`.gts\` component at a custom path 1`] = `
-"import Component from "@glimmer/component";
+exports[`generates a \`.gts\` template-only component 1`] = `
+"import type { TOC } from '@ember/component/template-only';
export interface FooSignature {
Args: {};
@@ -52,10 +49,25 @@ export interface FooSignature {
Element: null;
}
-export default class FooComponent extends Component {
-
- {{yield}}
-
+const Foo: TOC = {{yield}};
+
+export default Foo;
+"
+`;
+
+exports[`generates a \`.gts\` template-only component at a custom path 1`] = `
+"import type { TOC } from '@ember/component/template-only';
+
+export interface FooSignature {
+ Args: {};
+ Blocks: {
+ default: [];
+ };
+ Element: null;
}
+
+const Foo: TOC = {{yield}};
+
+export default Foo;
"
`;
diff --git a/test/generate-component.test.ts b/test/generate-component.test.ts
index 49f36e3..01db0c8 100644
--- a/test/generate-component.test.ts
+++ b/test/generate-component.test.ts
@@ -9,7 +9,7 @@ let cwd: string;
afterEach(() => fsExtra.remove(cwd));
-it("generates a `.gjs` component", async (ctx) => {
+it("generates a `.gjs` template-only component", async (ctx) => {
cwd = await copyBlueprint("v2-addon");
await generateComponent("foo", { cwd });
@@ -19,17 +19,17 @@ it("generates a `.gjs` component", async (ctx) => {
ctx.expect(content).toMatchSnapshot();
});
-it("generates a `.gts` component", async (ctx) => {
+it("generates a `.gjs` class-based component", async (ctx) => {
cwd = await copyBlueprint("v2-addon");
- await generateComponent("foo", { authoringFormat: "gts", cwd });
+ await generateComponent("foo", { classBased: true, cwd });
- const content = await readFile(join(cwd, "src/components/foo.gts"), "utf-8");
+ const content = await readFile(join(cwd, "src/components/foo.gjs"), "utf-8");
ctx.expect(content).toMatchSnapshot();
});
-it("generates a `.gjs` component at a custom path", async (ctx) => {
+it("generates a `.gjs` template-only component at a custom path", async (ctx) => {
cwd = await copyBlueprint("v2-addon");
await generateComponent("foo", { cwd, path: "src/-private" });
@@ -39,7 +39,31 @@ it("generates a `.gjs` component at a custom path", async (ctx) => {
ctx.expect(content).toMatchSnapshot();
});
-it("generates a `.gts` component at a custom path", async (ctx) => {
+it("generates a `.gts` template-only component", async (ctx) => {
+ cwd = await copyBlueprint("v2-addon");
+
+ await generateComponent("foo", { authoringFormat: "gts", cwd });
+
+ const content = await readFile(join(cwd, "src/components/foo.gts"), "utf-8");
+
+ ctx.expect(content).toMatchSnapshot();
+});
+
+it("generates a `.gts` class-based component", async (ctx) => {
+ cwd = await copyBlueprint("v2-addon");
+
+ await generateComponent("foo", {
+ authoringFormat: "gts",
+ classBased: true,
+ cwd,
+ });
+
+ const content = await readFile(join(cwd, "src/components/foo.gts"), "utf-8");
+
+ ctx.expect(content).toMatchSnapshot();
+});
+
+it("generates a `.gts` template-only component at a custom path", async (ctx) => {
cwd = await copyBlueprint("v2-addon");
await generateComponent("foo", {