@betterstart/cli 0.1.51 → 0.1.53
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/dist/cli.js +45 -74
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2539,13 +2539,18 @@ ${selectItems}
|
|
|
2539
2539
|
return ` <div className="space-y-4">
|
|
2540
2540
|
<FormLabel className="text-sm font-medium leading-none">${label}${requiredStar}</FormLabel>${hintJSX}
|
|
2541
2541
|
{${name}FieldArray.fields.map((item, index) => (
|
|
2542
|
-
<div key={item.id} className="
|
|
2543
|
-
<
|
|
2542
|
+
<div key={item.id} className="relative rounded-lg border p-4">
|
|
2543
|
+
<button
|
|
2544
|
+
type="button"
|
|
2545
|
+
onClick={() => ${name}FieldArray.remove(index)}
|
|
2546
|
+
className="absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-destructive/10 hover:text-destructive"
|
|
2547
|
+
>
|
|
2548
|
+
<Trash2 className="h-4 w-4" />
|
|
2549
|
+
<span className="sr-only">Remove</span>
|
|
2550
|
+
</button>
|
|
2551
|
+
<div className="space-y-4 pr-8">
|
|
2544
2552
|
${nestedFieldsJSX}
|
|
2545
2553
|
</div>
|
|
2546
|
-
<Button type="button" variant="ghost" size="sm" onClick={() => ${name}FieldArray.remove(index)}>
|
|
2547
|
-
Remove
|
|
2548
|
-
</Button>
|
|
2549
2554
|
</div>
|
|
2550
2555
|
))}
|
|
2551
2556
|
<Button
|
|
@@ -2575,10 +2580,10 @@ function generateMultiStepForm(schema, cwd, cmsDir, options) {
|
|
|
2575
2580
|
const zodFields = buildZodFields(allFields);
|
|
2576
2581
|
const defaults = buildDefaultValues(allFields);
|
|
2577
2582
|
const listFields = getListFields(allFields);
|
|
2578
|
-
const
|
|
2583
|
+
const hasListFields2 = listFields.length > 0;
|
|
2579
2584
|
const { setup: watchSetup } = buildWatchDecls(allFields);
|
|
2580
|
-
const rhfImport =
|
|
2581
|
-
const fieldArraySetup =
|
|
2585
|
+
const rhfImport = hasListFields2 ? `import { useFieldArray, useForm } from 'react-hook-form'` : `import { useForm } from 'react-hook-form'`;
|
|
2586
|
+
const fieldArraySetup = hasListFields2 ? `
|
|
2582
2587
|
${buildFieldArrayDecls(listFields)}
|
|
2583
2588
|
` : "";
|
|
2584
2589
|
const stepsConst = buildStepsConstant(steps, schema);
|
|
@@ -2600,7 +2605,6 @@ ${fieldsJSX}
|
|
|
2600
2605
|
const textareaImport = resolveUiImport(cwd, "textarea");
|
|
2601
2606
|
const selectImport = resolveUiImport(cwd, "select");
|
|
2602
2607
|
const radioGroupImport = resolveUiImport(cwd, "radio-group");
|
|
2603
|
-
const progressImport = resolveUiImport(cwd, "progress");
|
|
2604
2608
|
const mediaUploadImport = resolveUiImport(cwd, "media-upload-field");
|
|
2605
2609
|
const content = buildComponentSource({
|
|
2606
2610
|
pascal,
|
|
@@ -2614,7 +2618,6 @@ ${fieldsJSX}
|
|
|
2614
2618
|
textareaImport,
|
|
2615
2619
|
selectImport,
|
|
2616
2620
|
radioGroupImport,
|
|
2617
|
-
progressImport,
|
|
2618
2621
|
mediaUploadImport,
|
|
2619
2622
|
zodFields,
|
|
2620
2623
|
defaults,
|
|
@@ -2661,8 +2664,8 @@ export function ${p7.pascal}Form() {
|
|
|
2661
2664
|
return `'use client'
|
|
2662
2665
|
|
|
2663
2666
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
2664
|
-
import {
|
|
2665
|
-
import { parseAsInteger,
|
|
2667
|
+
import { ChevronLeft, ChevronRight${hasListFields ? ", Trash2" : ""} } from 'lucide-react'
|
|
2668
|
+
import { parseAsInteger, useQueryState } from 'nuqs'
|
|
2666
2669
|
import { useState } from 'react'
|
|
2667
2670
|
${p7.rhfImport}
|
|
2668
2671
|
import { z } from 'zod/v3'${queryClientImport}
|
|
@@ -2679,8 +2682,8 @@ import {
|
|
|
2679
2682
|
} from '${p7.formImport}'
|
|
2680
2683
|
import { Input } from '${p7.inputImport}'${p7.hasFileUpload ? `
|
|
2681
2684
|
import { MediaUploadField } from '${p7.mediaUploadImport}'` : ""}
|
|
2682
|
-
import {
|
|
2683
|
-
|
|
2685
|
+
${p7.hasRadio ? `import { RadioGroup, RadioGroupItem } from '${p7.radioGroupImport}'
|
|
2686
|
+
` : ""}
|
|
2684
2687
|
import { Textarea } from '${p7.textareaImport}'
|
|
2685
2688
|
import {
|
|
2686
2689
|
Select,
|
|
@@ -2700,8 +2703,6 @@ ${p7.stepsConst}
|
|
|
2700
2703
|
|
|
2701
2704
|
${formComponentDecl}() {
|
|
2702
2705
|
const [currentStep, setCurrentStep] = useQueryState('step', parseAsInteger.withDefault(0))
|
|
2703
|
-
const [completedStepsArr, setCompletedStepsArr] = useQueryState('completed', parseAsArrayOf(parseAsInteger).withDefault([]))
|
|
2704
|
-
const completedSteps = new Set(completedStepsArr)
|
|
2705
2706
|
const [submitted, setSubmitted] = useState(false)
|
|
2706
2707
|
const [submitting, setSubmitting] = useState(false)
|
|
2707
2708
|
|
|
@@ -2718,9 +2719,6 @@ ${p7.fieldArraySetup}${p7.watchSetup}
|
|
|
2718
2719
|
STEPS[currentStep].fields as (keyof FormValues)[]
|
|
2719
2720
|
)
|
|
2720
2721
|
if (isValid) {
|
|
2721
|
-
if (!completedSteps.has(currentStep)) {
|
|
2722
|
-
setCompletedStepsArr([...completedStepsArr, currentStep])
|
|
2723
|
-
}
|
|
2724
2722
|
setCurrentStep(currentStep + 1)
|
|
2725
2723
|
}
|
|
2726
2724
|
}
|
|
@@ -2729,12 +2727,6 @@ ${p7.fieldArraySetup}${p7.watchSetup}
|
|
|
2729
2727
|
setCurrentStep(currentStep - 1)
|
|
2730
2728
|
}
|
|
2731
2729
|
|
|
2732
|
-
function handleStepClick(index: number) {
|
|
2733
|
-
if (index < currentStep || completedSteps.has(index)) {
|
|
2734
|
-
setCurrentStep(index)
|
|
2735
|
-
}
|
|
2736
|
-
}
|
|
2737
|
-
|
|
2738
2730
|
async function onSubmit(values: FormValues) {
|
|
2739
2731
|
setSubmitting(true)
|
|
2740
2732
|
try {
|
|
@@ -2763,48 +2755,6 @@ ${p7.fieldArraySetup}${p7.watchSetup}
|
|
|
2763
2755
|
return (
|
|
2764
2756
|
<Form {...form}>
|
|
2765
2757
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
2766
|
-
{/* Mobile step indicator */}
|
|
2767
|
-
<div className="md:hidden space-y-2">
|
|
2768
|
-
<p className="text-sm text-muted-foreground">
|
|
2769
|
-
Step {currentStep + 1} of {STEPS.length} — {STEPS[currentStep].label}
|
|
2770
|
-
</p>
|
|
2771
|
-
<Progress value={((currentStep + 1) / STEPS.length) * 100} />
|
|
2772
|
-
</div>
|
|
2773
|
-
|
|
2774
|
-
{/* Desktop step indicator */}
|
|
2775
|
-
<nav className="hidden md:flex items-center justify-center" aria-label="Form progress">
|
|
2776
|
-
{STEPS.map((step, index) => (
|
|
2777
|
-
<div key={step.name} className="flex items-center">
|
|
2778
|
-
<button
|
|
2779
|
-
type="button"
|
|
2780
|
-
onClick={() => handleStepClick(index)}
|
|
2781
|
-
disabled={index > currentStep && !completedSteps.has(index)}
|
|
2782
|
-
aria-current={index === currentStep ? 'step' : undefined}
|
|
2783
|
-
className={\`flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium transition-colors \${
|
|
2784
|
-
completedSteps.has(index)
|
|
2785
|
-
? 'bg-primary text-primary-foreground cursor-pointer'
|
|
2786
|
-
: index === currentStep
|
|
2787
|
-
? 'border-2 border-primary text-primary'
|
|
2788
|
-
: 'border-2 border-muted text-muted-foreground'
|
|
2789
|
-
}\`}
|
|
2790
|
-
>
|
|
2791
|
-
{completedSteps.has(index) ? (
|
|
2792
|
-
<Check className="h-4 w-4" />
|
|
2793
|
-
) : (
|
|
2794
|
-
index + 1
|
|
2795
|
-
)}
|
|
2796
|
-
</button>
|
|
2797
|
-
{index < STEPS.length - 1 && (
|
|
2798
|
-
<div
|
|
2799
|
-
className={\`h-0.5 w-8 mx-1 \${
|
|
2800
|
-
completedSteps.has(index) ? 'bg-primary' : 'bg-muted'
|
|
2801
|
-
}\`}
|
|
2802
|
-
/>
|
|
2803
|
-
)}
|
|
2804
|
-
</div>
|
|
2805
|
-
))}
|
|
2806
|
-
</nav>
|
|
2807
|
-
|
|
2808
2758
|
{/* Step header */}
|
|
2809
2759
|
<div>
|
|
2810
2760
|
<h3 className="text-lg font-semibold">{STEPS[currentStep].label}</h3>
|
|
@@ -2868,14 +2818,14 @@ function generateSingleStepForm(schema, cwd, cmsDir, options) {
|
|
|
2868
2818
|
const zodFields = buildZodFields(fields);
|
|
2869
2819
|
const defaults = buildDefaultValues(fields);
|
|
2870
2820
|
const listFields = getListFields(fields);
|
|
2871
|
-
const
|
|
2821
|
+
const hasListFields2 = listFields.length > 0;
|
|
2872
2822
|
const { setup: watchSetup } = buildWatchDecls(fields);
|
|
2873
2823
|
const rawFields = schema.fields || [];
|
|
2874
2824
|
const fieldJSX = renderFieldsJSX(rawFields);
|
|
2875
2825
|
const submitText = schema.submitButtonText || "Submit";
|
|
2876
2826
|
const successMessage = escapeJsx(schema.successMessage || "Form submitted successfully!");
|
|
2877
|
-
const rhfImport =
|
|
2878
|
-
const fieldArraySetup =
|
|
2827
|
+
const rhfImport = hasListFields2 ? `import { useFieldArray, useForm } from 'react-hook-form'` : `import { useForm } from 'react-hook-form'`;
|
|
2828
|
+
const fieldArraySetup = hasListFields2 ? `
|
|
2879
2829
|
${buildFieldArrayDecls(listFields)}
|
|
2880
2830
|
` : "";
|
|
2881
2831
|
const hasRadio = fields.some((f) => f.type === "radio");
|
|
@@ -2902,9 +2852,11 @@ export function ${pascal}Form() {
|
|
|
2902
2852
|
)
|
|
2903
2853
|
}
|
|
2904
2854
|
` : "";
|
|
2855
|
+
const lucideImport = hasListFields2 ? `
|
|
2856
|
+
import { Trash2 } from 'lucide-react'` : "";
|
|
2905
2857
|
const content = `'use client'
|
|
2906
2858
|
|
|
2907
|
-
import { zodResolver } from '@hookform/resolvers/zod'
|
|
2859
|
+
import { zodResolver } from '@hookform/resolvers/zod'${lucideImport}
|
|
2908
2860
|
import { useState } from 'react'
|
|
2909
2861
|
${rhfImport}
|
|
2910
2862
|
import { z } from 'zod/v3'${queryClientImport}
|
|
@@ -15605,9 +15557,28 @@ var updateComponentCommand = new Command7("update-component").description("Updat
|
|
|
15605
15557
|
const all = getAllComponentNames();
|
|
15606
15558
|
clack2.intro("Available components");
|
|
15607
15559
|
const uiComponents = getStaticUiComponents();
|
|
15608
|
-
|
|
15609
|
-
|
|
15610
|
-
|
|
15560
|
+
const templateKeys = Object.keys(TEMPLATE_REGISTRY).sort();
|
|
15561
|
+
console.log();
|
|
15562
|
+
console.log(` UI Components (${uiComponents.length})`);
|
|
15563
|
+
console.log(` ${"\u2500".repeat(50)}`);
|
|
15564
|
+
console.log(` ${"Name".padEnd(28)} ${"Path"}`);
|
|
15565
|
+
console.log(` ${"\u2500".repeat(50)}`);
|
|
15566
|
+
for (const name of uiComponents) {
|
|
15567
|
+
console.log(` ${name.padEnd(28)} components/ui/${name}.tsx`);
|
|
15568
|
+
}
|
|
15569
|
+
console.log();
|
|
15570
|
+
console.log(` Template Components (${templateKeys.length})`);
|
|
15571
|
+
console.log(` ${"\u2500".repeat(56)}`);
|
|
15572
|
+
console.log(` ${"Name".padEnd(28)} ${"Path"}`);
|
|
15573
|
+
console.log(` ${"\u2500".repeat(56)}`);
|
|
15574
|
+
for (const name of templateKeys) {
|
|
15575
|
+
console.log(` ${name.padEnd(28)} ${TEMPLATE_REGISTRY[name].relPath}`);
|
|
15576
|
+
}
|
|
15577
|
+
console.log();
|
|
15578
|
+
console.log(` Special`);
|
|
15579
|
+
console.log(` ${"\u2500".repeat(56)}`);
|
|
15580
|
+
console.log(` ${"tiptap".padEnd(28)} components/ui/tiptap/ (all files)`);
|
|
15581
|
+
console.log();
|
|
15611
15582
|
clack2.outro(`${all.length} components available`);
|
|
15612
15583
|
return;
|
|
15613
15584
|
}
|