@hustle-together/api-dev-tools 3.11.1 → 3.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/code-reviewer.md +170 -0
- package/.claude/agents/docs-generator.md +80 -0
- package/.claude/agents/implementation-reviewer.md +119 -0
- package/.claude/agents/parallel-researcher.md +52 -0
- package/.claude/agents/research-validator.md +116 -0
- package/.claude/agents/schema-generator.md +70 -0
- package/.claude/agents/test-writer.md +104 -0
- package/.claude/api-dev-state.json +305 -56
- package/.claude/commands/README.md +21 -10
- package/.claude/commands/add-command.md +8 -5
- package/.claude/commands/api-create.md +36 -25
- package/.claude/commands/api-env.md +1 -0
- package/.claude/commands/api-interview.md +32 -19
- package/.claude/commands/api-research.md +47 -21
- package/.claude/commands/api-status.md +21 -1
- package/.claude/commands/api-verify.md +14 -13
- package/.claude/commands/beepboop.md +4 -5
- package/.claude/commands/busycommit.md +2 -3
- package/.claude/commands/commit.md +2 -3
- package/.claude/commands/cycle.md +2 -7
- package/.claude/commands/gap.md +2 -3
- package/.claude/commands/green.md +2 -7
- package/.claude/commands/issue.md +3 -8
- package/.claude/commands/ntfy-setup.md +91 -0
- package/.claude/commands/ntfy-test.md +74 -0
- package/.claude/commands/plan.md +2 -3
- package/.claude/commands/pr.md +2 -3
- package/.claude/commands/publish.md +40 -0
- package/.claude/commands/red.md +2 -7
- package/.claude/commands/refactor.md +2 -7
- package/.claude/commands/spike.md +2 -7
- package/.claude/commands/summarize.md +2 -3
- package/.claude/commands/tdd.md +2 -7
- package/.claude/commands/worktree-add.md +208 -216
- package/.claude/commands/worktree-cleanup.md +172 -178
- package/.claude/settings.json +63 -12
- package/.claude/settings.local.json +2 -1
- package/.claude-plugin/marketplace.json +2 -11
- package/.skills/README.md +55 -53
- package/.skills/_shared/settings.json +1 -1
- package/.skills/add-command/SKILL.md +10 -5
- package/.skills/api-create/SKILL.md +146 -35
- package/.skills/api-env/SKILL.md +1 -0
- package/.skills/api-interview/SKILL.md +32 -19
- package/.skills/api-research/SKILL.md +47 -21
- package/.skills/api-status/SKILL.md +21 -1
- package/.skills/api-verify/SKILL.md +14 -13
- package/.skills/beepboop/SKILL.md +6 -5
- package/.skills/busycommit/SKILL.md +4 -3
- package/.skills/commit/SKILL.md +4 -3
- package/.skills/cycle/SKILL.md +4 -7
- package/.skills/gap/SKILL.md +4 -3
- package/.skills/green/SKILL.md +4 -7
- package/.skills/issue/SKILL.md +5 -8
- package/.skills/plan/SKILL.md +4 -3
- package/.skills/pr/SKILL.md +4 -3
- package/.skills/publish/SKILL.md +160 -0
- package/.skills/red/SKILL.md +4 -7
- package/.skills/refactor/SKILL.md +4 -7
- package/.skills/spike/SKILL.md +4 -7
- package/.skills/summarize/SKILL.md +4 -3
- package/.skills/tdd/SKILL.md +4 -7
- package/.skills/update-todos/SKILL.md +22 -0
- package/.skills/worktree-add/SKILL.md +210 -216
- package/.skills/worktree-cleanup/SKILL.md +183 -187
- package/CHANGELOG.md +97 -79
- package/README.md +161 -7142
- package/bin/cli.js +448 -805
- package/commands/README.md +66 -31
- package/commands/add-command.md +8 -5
- package/commands/beepboop.md +4 -5
- package/commands/busycommit.md +2 -3
- package/commands/commit.md +2 -3
- package/commands/cycle.md +2 -7
- package/commands/gap.md +2 -3
- package/commands/green.md +2 -7
- package/commands/hustle-api-continue.md +8 -5
- package/commands/hustle-api-create.md +70 -29
- package/commands/hustle-api-env.md +1 -0
- package/commands/hustle-api-interview.md +32 -19
- package/commands/hustle-api-research.md +47 -21
- package/commands/hustle-api-sessions.md +8 -7
- package/commands/hustle-api-status.md +21 -1
- package/commands/hustle-api-verify.md +14 -13
- package/commands/hustle-combine.md +488 -241
- package/commands/hustle-ui-create-page.md +113 -50
- package/commands/hustle-ui-create.md +179 -26
- package/commands/issue.md +3 -8
- package/commands/plan.md +2 -3
- package/commands/pr.md +2 -3
- package/commands/red.md +2 -7
- package/commands/refactor.md +2 -7
- package/commands/spike.md +2 -7
- package/commands/summarize.md +2 -3
- package/commands/tdd.md +2 -7
- package/commands/worktree-add.md +208 -216
- package/commands/worktree-cleanup.md +172 -178
- package/hooks/api-workflow-check.py +5 -3
- package/hooks/enforce-component-type-confirm.py +97 -0
- package/hooks/lib/__init__.py +1 -0
- package/hooks/lib/greptile.py +355 -0
- package/hooks/lib/ntfy.py +209 -0
- package/hooks/notify-input-needed.py +73 -0
- package/hooks/notify-phase-complete.py +90 -0
- package/hooks/run-code-review.py +246 -0
- package/hooks/track-token-usage.py +121 -0
- package/package.json +13 -3
- package/scripts/collect-test-results.ts +102 -77
- package/scripts/extract-parameters.ts +112 -70
- package/scripts/generate-test-manifest.ts +118 -77
- package/templates/.env.example +57 -0
- package/templates/BRAND_GUIDE.md +92 -52
- package/templates/CLAUDE-SECTION.md +40 -37
- package/templates/SPEC.json +186 -38
- package/templates/api-dev-state.json +33 -4
- package/templates/api-showcase/_components/APICard.tsx +22 -18
- package/templates/api-showcase/_components/APIModal.tsx +110 -64
- package/templates/api-showcase/_components/APIShowcase.tsx +53 -35
- package/templates/api-showcase/_components/APITester.tsx +128 -67
- package/templates/api-showcase/page.tsx +4 -4
- package/templates/api-test/page.tsx +51 -30
- package/templates/api-test/test-structure/route.ts +43 -34
- package/templates/component/Component.stories.tsx +41 -39
- package/templates/component/Component.test.tsx +96 -78
- package/templates/component/Component.tsx +63 -52
- package/templates/component/Component.types.ts +10 -6
- package/templates/component/Component.visual.spec.ts +170 -0
- package/templates/component/index.ts +2 -2
- package/templates/dev-tools/_components/DevToolsLanding.tsx +8 -8
- package/templates/dev-tools/page.tsx +4 -3
- package/templates/mcp-servers.json +30 -2
- package/templates/page/page.e2e.test.ts +56 -48
- package/templates/page/page.tsx +3 -3
- package/templates/shared/HeroHeader.tsx +16 -15
- package/templates/shared/index.ts +1 -1
- package/templates/ui-showcase/_components/PreviewCard.tsx +20 -20
- package/templates/ui-showcase/_components/PreviewModal.tsx +149 -108
- package/templates/ui-showcase/_components/UIShowcase.tsx +43 -35
- package/templates/ui-showcase/page.tsx +4 -4
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* @generated by @hustle-together/api-dev-tools v3.0
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { NextRequest, NextResponse } from
|
|
11
|
-
import fs from
|
|
12
|
-
import path from
|
|
10
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
11
|
+
import fs from "fs";
|
|
12
|
+
import path from "path";
|
|
13
13
|
|
|
14
14
|
// ============================================
|
|
15
15
|
// Types
|
|
@@ -18,7 +18,7 @@ import path from 'path';
|
|
|
18
18
|
interface TestCase {
|
|
19
19
|
name: string;
|
|
20
20
|
line: number;
|
|
21
|
-
status:
|
|
21
|
+
status: "pending" | "passed" | "failed" | "skipped";
|
|
22
22
|
duration?: number;
|
|
23
23
|
error?: string;
|
|
24
24
|
}
|
|
@@ -58,7 +58,7 @@ interface TestStructure {
|
|
|
58
58
|
* Uses brace counting to handle nested structures
|
|
59
59
|
*/
|
|
60
60
|
function parseTestFile(content: string, filePath: string): TestFeature {
|
|
61
|
-
const lines = content.split(
|
|
61
|
+
const lines = content.split("\n");
|
|
62
62
|
const rootGroups: TestGroup[] = [];
|
|
63
63
|
const groupStack: TestGroup[] = [];
|
|
64
64
|
|
|
@@ -77,7 +77,7 @@ function parseTestFile(content: string, filePath: string): TestFeature {
|
|
|
77
77
|
name: describeMatch[1],
|
|
78
78
|
line: lineNum,
|
|
79
79
|
tests: [],
|
|
80
|
-
groups: []
|
|
80
|
+
groups: [],
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
if (groupStack.length > 0) {
|
|
@@ -97,12 +97,12 @@ function parseTestFile(content: string, filePath: string): TestFeature {
|
|
|
97
97
|
const testCase: TestCase = {
|
|
98
98
|
name: testMatch[1],
|
|
99
99
|
line: lineNum,
|
|
100
|
-
status:
|
|
100
|
+
status: "pending", // Will be updated by test runner results
|
|
101
101
|
};
|
|
102
102
|
|
|
103
103
|
// Check for .skip or .todo
|
|
104
|
-
if (line.includes(
|
|
105
|
-
testCase.status =
|
|
104
|
+
if (line.includes(".skip") || line.includes(".todo")) {
|
|
105
|
+
testCase.status = "skipped";
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
groupStack[groupStack.length - 1].tests.push(testCase);
|
|
@@ -114,7 +114,11 @@ function parseTestFile(content: string, filePath: string): TestFeature {
|
|
|
114
114
|
braceCount += openBraces - closeBraces;
|
|
115
115
|
|
|
116
116
|
// Pop group from stack when we close its scope
|
|
117
|
-
if (
|
|
117
|
+
if (
|
|
118
|
+
inDescribe &&
|
|
119
|
+
braceCount <= currentDescribeBraceStart &&
|
|
120
|
+
groupStack.length > 0
|
|
121
|
+
) {
|
|
118
122
|
groupStack.pop();
|
|
119
123
|
if (groupStack.length === 0) {
|
|
120
124
|
inDescribe = false;
|
|
@@ -126,15 +130,20 @@ function parseTestFile(content: string, filePath: string): TestFeature {
|
|
|
126
130
|
}
|
|
127
131
|
|
|
128
132
|
// Count tests
|
|
129
|
-
const countTests = (
|
|
130
|
-
|
|
133
|
+
const countTests = (
|
|
134
|
+
groups: TestGroup[],
|
|
135
|
+
): { total: number; passed: number; failed: number; skipped: number } => {
|
|
136
|
+
let total = 0,
|
|
137
|
+
passed = 0,
|
|
138
|
+
failed = 0,
|
|
139
|
+
skipped = 0;
|
|
131
140
|
|
|
132
141
|
for (const group of groups) {
|
|
133
142
|
for (const test of group.tests) {
|
|
134
143
|
total++;
|
|
135
|
-
if (test.status ===
|
|
136
|
-
else if (test.status ===
|
|
137
|
-
else if (test.status ===
|
|
144
|
+
if (test.status === "passed") passed++;
|
|
145
|
+
else if (test.status === "failed") failed++;
|
|
146
|
+
else if (test.status === "skipped") skipped++;
|
|
138
147
|
}
|
|
139
148
|
const nested = countTests(group.groups);
|
|
140
149
|
total += nested.total;
|
|
@@ -155,7 +164,7 @@ function parseTestFile(content: string, filePath: string): TestFeature {
|
|
|
155
164
|
totalTests: counts.total,
|
|
156
165
|
passedTests: counts.passed,
|
|
157
166
|
failedTests: counts.failed,
|
|
158
|
-
skippedTests: counts.skipped
|
|
167
|
+
skippedTests: counts.skipped,
|
|
159
168
|
};
|
|
160
169
|
}
|
|
161
170
|
|
|
@@ -165,12 +174,12 @@ function parseTestFile(content: string, filePath: string): TestFeature {
|
|
|
165
174
|
function findTestFiles(baseDir: string): string[] {
|
|
166
175
|
const testFiles: string[] = [];
|
|
167
176
|
const testPatterns = [
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
177
|
+
"**/*.test.ts",
|
|
178
|
+
"**/*.test.tsx",
|
|
179
|
+
"**/*.spec.ts",
|
|
180
|
+
"**/*.spec.tsx",
|
|
181
|
+
"**/__tests__/**/*.ts",
|
|
182
|
+
"**/__tests__/**/*.tsx",
|
|
174
183
|
];
|
|
175
184
|
|
|
176
185
|
function walkDir(dir: string) {
|
|
@@ -182,17 +191,17 @@ function findTestFiles(baseDir: string): string[] {
|
|
|
182
191
|
|
|
183
192
|
// Skip node_modules and hidden directories
|
|
184
193
|
if (entry.isDirectory()) {
|
|
185
|
-
if (entry.name ===
|
|
194
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".")) {
|
|
186
195
|
continue;
|
|
187
196
|
}
|
|
188
197
|
walkDir(fullPath);
|
|
189
198
|
} else if (entry.isFile()) {
|
|
190
199
|
// Check if file matches test patterns
|
|
191
200
|
if (
|
|
192
|
-
entry.name.endsWith(
|
|
193
|
-
entry.name.endsWith(
|
|
194
|
-
entry.name.endsWith(
|
|
195
|
-
entry.name.endsWith(
|
|
201
|
+
entry.name.endsWith(".test.ts") ||
|
|
202
|
+
entry.name.endsWith(".test.tsx") ||
|
|
203
|
+
entry.name.endsWith(".spec.ts") ||
|
|
204
|
+
entry.name.endsWith(".spec.tsx")
|
|
196
205
|
) {
|
|
197
206
|
testFiles.push(fullPath);
|
|
198
207
|
}
|
|
@@ -214,7 +223,7 @@ function findTestFiles(baseDir: string): string[] {
|
|
|
214
223
|
export async function GET(request: NextRequest) {
|
|
215
224
|
try {
|
|
216
225
|
const { searchParams } = new URL(request.url);
|
|
217
|
-
const testPath = searchParams.get(
|
|
226
|
+
const testPath = searchParams.get("path");
|
|
218
227
|
const baseDir = process.cwd();
|
|
219
228
|
|
|
220
229
|
let testFiles: string[];
|
|
@@ -225,7 +234,7 @@ export async function GET(request: NextRequest) {
|
|
|
225
234
|
if (!fs.existsSync(fullPath)) {
|
|
226
235
|
return NextResponse.json(
|
|
227
236
|
{ error: `Test file not found: ${testPath}` },
|
|
228
|
-
{ status: 404 }
|
|
237
|
+
{ status: 404 },
|
|
229
238
|
);
|
|
230
239
|
}
|
|
231
240
|
testFiles = [fullPath];
|
|
@@ -238,7 +247,7 @@ export async function GET(request: NextRequest) {
|
|
|
238
247
|
|
|
239
248
|
for (const file of testFiles) {
|
|
240
249
|
try {
|
|
241
|
-
const content = fs.readFileSync(file,
|
|
250
|
+
const content = fs.readFileSync(file, "utf-8");
|
|
242
251
|
const relativePath = path.relative(baseDir, file);
|
|
243
252
|
const feature = parseTestFile(content, relativePath);
|
|
244
253
|
features.push(feature);
|
|
@@ -255,15 +264,15 @@ export async function GET(request: NextRequest) {
|
|
|
255
264
|
passedTests: features.reduce((sum, f) => sum + f.passedTests, 0),
|
|
256
265
|
failedTests: features.reduce((sum, f) => sum + f.failedTests, 0),
|
|
257
266
|
skippedTests: features.reduce((sum, f) => sum + f.skippedTests, 0),
|
|
258
|
-
parsedAt: new Date().toISOString()
|
|
267
|
+
parsedAt: new Date().toISOString(),
|
|
259
268
|
};
|
|
260
269
|
|
|
261
270
|
return NextResponse.json(structure);
|
|
262
271
|
} catch (error) {
|
|
263
|
-
console.error(
|
|
272
|
+
console.error("Test structure parser error:", error);
|
|
264
273
|
return NextResponse.json(
|
|
265
|
-
{ error:
|
|
266
|
-
{ status: 500 }
|
|
274
|
+
{ error: "Failed to parse test structure", details: String(error) },
|
|
275
|
+
{ status: 500 },
|
|
267
276
|
);
|
|
268
277
|
}
|
|
269
278
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from
|
|
2
|
-
import { __COMPONENT_NAME__ } from
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { __COMPONENT_NAME__ } from "./__COMPONENT_NAME__";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* __COMPONENT_NAME__ - __COMPONENT_DESCRIPTION__
|
|
@@ -7,51 +7,51 @@ import { __COMPONENT_NAME__ } from './__COMPONENT_NAME__';
|
|
|
7
7
|
* This component was created using the Hustle UI Create workflow.
|
|
8
8
|
*/
|
|
9
9
|
const meta: Meta<typeof __COMPONENT_NAME__> = {
|
|
10
|
-
title:
|
|
10
|
+
title: "Components/__COMPONENT_NAME__",
|
|
11
11
|
component: __COMPONENT_NAME__,
|
|
12
12
|
parameters: {
|
|
13
|
-
layout:
|
|
13
|
+
layout: "centered",
|
|
14
14
|
docs: {
|
|
15
15
|
description: {
|
|
16
|
-
component:
|
|
16
|
+
component: "__COMPONENT_DESCRIPTION__",
|
|
17
17
|
},
|
|
18
18
|
},
|
|
19
19
|
},
|
|
20
|
-
tags: [
|
|
20
|
+
tags: ["autodocs"],
|
|
21
21
|
argTypes: {
|
|
22
22
|
variant: {
|
|
23
|
-
control:
|
|
24
|
-
options: [
|
|
25
|
-
description:
|
|
23
|
+
control: "select",
|
|
24
|
+
options: ["primary", "secondary", "destructive", "outline", "ghost"],
|
|
25
|
+
description: "Visual style variant",
|
|
26
26
|
table: {
|
|
27
|
-
defaultValue: { summary:
|
|
27
|
+
defaultValue: { summary: "primary" },
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
30
|
size: {
|
|
31
|
-
control:
|
|
32
|
-
options: [
|
|
33
|
-
description:
|
|
31
|
+
control: "select",
|
|
32
|
+
options: ["sm", "md", "lg"],
|
|
33
|
+
description: "Size variant",
|
|
34
34
|
table: {
|
|
35
|
-
defaultValue: { summary:
|
|
35
|
+
defaultValue: { summary: "md" },
|
|
36
36
|
},
|
|
37
37
|
},
|
|
38
38
|
loading: {
|
|
39
|
-
control:
|
|
40
|
-
description:
|
|
39
|
+
control: "boolean",
|
|
40
|
+
description: "Shows loading spinner",
|
|
41
41
|
table: {
|
|
42
|
-
defaultValue: { summary:
|
|
42
|
+
defaultValue: { summary: "false" },
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
disabled: {
|
|
46
|
-
control:
|
|
47
|
-
description:
|
|
46
|
+
control: "boolean",
|
|
47
|
+
description: "Disables the component",
|
|
48
48
|
table: {
|
|
49
|
-
defaultValue: { summary:
|
|
49
|
+
defaultValue: { summary: "false" },
|
|
50
50
|
},
|
|
51
51
|
},
|
|
52
52
|
children: {
|
|
53
|
-
control:
|
|
54
|
-
description:
|
|
53
|
+
control: "text",
|
|
54
|
+
description: "Content inside the component",
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
};
|
|
@@ -64,8 +64,8 @@ type Story = StoryObj<typeof meta>;
|
|
|
64
64
|
*/
|
|
65
65
|
export const Primary: Story = {
|
|
66
66
|
args: {
|
|
67
|
-
variant:
|
|
68
|
-
children:
|
|
67
|
+
variant: "primary",
|
|
68
|
+
children: "Primary __COMPONENT_NAME__",
|
|
69
69
|
},
|
|
70
70
|
};
|
|
71
71
|
|
|
@@ -74,8 +74,8 @@ export const Primary: Story = {
|
|
|
74
74
|
*/
|
|
75
75
|
export const Secondary: Story = {
|
|
76
76
|
args: {
|
|
77
|
-
variant:
|
|
78
|
-
children:
|
|
77
|
+
variant: "secondary",
|
|
78
|
+
children: "Secondary __COMPONENT_NAME__",
|
|
79
79
|
},
|
|
80
80
|
};
|
|
81
81
|
|
|
@@ -84,8 +84,8 @@ export const Secondary: Story = {
|
|
|
84
84
|
*/
|
|
85
85
|
export const Destructive: Story = {
|
|
86
86
|
args: {
|
|
87
|
-
variant:
|
|
88
|
-
children:
|
|
87
|
+
variant: "destructive",
|
|
88
|
+
children: "Delete Item",
|
|
89
89
|
},
|
|
90
90
|
};
|
|
91
91
|
|
|
@@ -94,8 +94,8 @@ export const Destructive: Story = {
|
|
|
94
94
|
*/
|
|
95
95
|
export const Outline: Story = {
|
|
96
96
|
args: {
|
|
97
|
-
variant:
|
|
98
|
-
children:
|
|
97
|
+
variant: "outline",
|
|
98
|
+
children: "Outline __COMPONENT_NAME__",
|
|
99
99
|
},
|
|
100
100
|
};
|
|
101
101
|
|
|
@@ -104,8 +104,8 @@ export const Outline: Story = {
|
|
|
104
104
|
*/
|
|
105
105
|
export const Ghost: Story = {
|
|
106
106
|
args: {
|
|
107
|
-
variant:
|
|
108
|
-
children:
|
|
107
|
+
variant: "ghost",
|
|
108
|
+
children: "Ghost __COMPONENT_NAME__",
|
|
109
109
|
},
|
|
110
110
|
};
|
|
111
111
|
|
|
@@ -114,8 +114,8 @@ export const Ghost: Story = {
|
|
|
114
114
|
*/
|
|
115
115
|
export const Small: Story = {
|
|
116
116
|
args: {
|
|
117
|
-
size:
|
|
118
|
-
children:
|
|
117
|
+
size: "sm",
|
|
118
|
+
children: "Small __COMPONENT_NAME__",
|
|
119
119
|
},
|
|
120
120
|
};
|
|
121
121
|
|
|
@@ -124,8 +124,8 @@ export const Small: Story = {
|
|
|
124
124
|
*/
|
|
125
125
|
export const Large: Story = {
|
|
126
126
|
args: {
|
|
127
|
-
size:
|
|
128
|
-
children:
|
|
127
|
+
size: "lg",
|
|
128
|
+
children: "Large __COMPONENT_NAME__",
|
|
129
129
|
},
|
|
130
130
|
};
|
|
131
131
|
|
|
@@ -135,7 +135,7 @@ export const Large: Story = {
|
|
|
135
135
|
export const Loading: Story = {
|
|
136
136
|
args: {
|
|
137
137
|
loading: true,
|
|
138
|
-
children:
|
|
138
|
+
children: "Loading...",
|
|
139
139
|
},
|
|
140
140
|
};
|
|
141
141
|
|
|
@@ -145,7 +145,7 @@ export const Loading: Story = {
|
|
|
145
145
|
export const Disabled: Story = {
|
|
146
146
|
args: {
|
|
147
147
|
disabled: true,
|
|
148
|
-
children:
|
|
148
|
+
children: "Disabled __COMPONENT_NAME__",
|
|
149
149
|
},
|
|
150
150
|
};
|
|
151
151
|
|
|
@@ -158,7 +158,9 @@ export const AllVariants: Story = {
|
|
|
158
158
|
<div className="flex gap-2">
|
|
159
159
|
<__COMPONENT_NAME__ variant="primary">Primary</__COMPONENT_NAME__>
|
|
160
160
|
<__COMPONENT_NAME__ variant="secondary">Secondary</__COMPONENT_NAME__>
|
|
161
|
-
<__COMPONENT_NAME__ variant="destructive">
|
|
161
|
+
<__COMPONENT_NAME__ variant="destructive">
|
|
162
|
+
Destructive
|
|
163
|
+
</__COMPONENT_NAME__>
|
|
162
164
|
<__COMPONENT_NAME__ variant="outline">Outline</__COMPONENT_NAME__>
|
|
163
165
|
<__COMPONENT_NAME__ variant="ghost">Ghost</__COMPONENT_NAME__>
|
|
164
166
|
</div>
|