@betterstart/cli 0.1.46 → 0.1.48
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 +73 -11
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/templates/ui/media-upload-field.tsx +18 -4
package/dist/cli.js
CHANGED
|
@@ -2437,7 +2437,7 @@ ${optionItems}
|
|
|
2437
2437
|
return generateTextFieldJSX(name, label, placeholder || "+1 (555) 000-0000", hintJSX, requiredStar, "tel");
|
|
2438
2438
|
case "file":
|
|
2439
2439
|
case "upload":
|
|
2440
|
-
return
|
|
2440
|
+
return generateFileUploadFieldJSX(field, name, label, hintJSX, requiredStar);
|
|
2441
2441
|
case "list":
|
|
2442
2442
|
return generateListFieldJSX(field, name, label, hintPlainJSX, requiredStar);
|
|
2443
2443
|
default:
|
|
@@ -2459,6 +2459,30 @@ function generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, i
|
|
|
2459
2459
|
)}
|
|
2460
2460
|
/>`;
|
|
2461
2461
|
}
|
|
2462
|
+
function generateFileUploadFieldJSX(field, name, label, hintJSX, requiredStar) {
|
|
2463
|
+
const accept = field.accept || "*/*";
|
|
2464
|
+
const maxSize = field.maxFileSize || 10;
|
|
2465
|
+
return ` <FormField
|
|
2466
|
+
control={form.control}
|
|
2467
|
+
name="${name}"
|
|
2468
|
+
render={({ field }) => (
|
|
2469
|
+
<FormItem>
|
|
2470
|
+
<FormLabel>${label}${requiredStar}</FormLabel>
|
|
2471
|
+
<FormControl>
|
|
2472
|
+
<MediaUploadField
|
|
2473
|
+
value={field.value}
|
|
2474
|
+
onChange={field.onChange}
|
|
2475
|
+
onBlur={field.onBlur}
|
|
2476
|
+
accept="${accept}"
|
|
2477
|
+
maxSizeInMB={${maxSize}}
|
|
2478
|
+
label=""
|
|
2479
|
+
/>
|
|
2480
|
+
</FormControl>${hintJSX}
|
|
2481
|
+
<FormMessage />
|
|
2482
|
+
</FormItem>
|
|
2483
|
+
)}
|
|
2484
|
+
/>`;
|
|
2485
|
+
}
|
|
2462
2486
|
function generateListFieldJSX(field, name, label, hintJSX, requiredStar) {
|
|
2463
2487
|
if (!field.fields || field.fields.length === 0) {
|
|
2464
2488
|
return generateTextFieldJSX(name, label, field.placeholder || "", hintJSX, requiredStar, "text");
|
|
@@ -2569,6 +2593,7 @@ ${fieldsJSX}
|
|
|
2569
2593
|
const submitText = schema.submitButtonText || "Submit";
|
|
2570
2594
|
const successMessage = escapeJsx(schema.successMessage || "Form submitted successfully!");
|
|
2571
2595
|
const hasRadio = allFields.some((f) => f.type === "radio");
|
|
2596
|
+
const hasFileUpload = allFields.some((f) => f.type === "file" || f.type === "upload");
|
|
2572
2597
|
const buttonImport = resolveUiImport(cwd, "button");
|
|
2573
2598
|
const formImport = resolveUiImport(cwd, "form");
|
|
2574
2599
|
const inputImport = resolveUiImport(cwd, "input");
|
|
@@ -2576,11 +2601,13 @@ ${fieldsJSX}
|
|
|
2576
2601
|
const selectImport = resolveUiImport(cwd, "select");
|
|
2577
2602
|
const radioGroupImport = resolveUiImport(cwd, "radio-group");
|
|
2578
2603
|
const progressImport = resolveUiImport(cwd, "progress");
|
|
2604
|
+
const mediaUploadImport = resolveUiImport(cwd, "media-upload-field");
|
|
2579
2605
|
const content = buildComponentSource({
|
|
2580
2606
|
pascal,
|
|
2581
2607
|
kebab,
|
|
2582
2608
|
rhfImport,
|
|
2583
2609
|
hasRadio,
|
|
2610
|
+
hasFileUpload,
|
|
2584
2611
|
buttonImport,
|
|
2585
2612
|
formImport,
|
|
2586
2613
|
inputImport,
|
|
@@ -2588,6 +2615,7 @@ ${fieldsJSX}
|
|
|
2588
2615
|
selectImport,
|
|
2589
2616
|
radioGroupImport,
|
|
2590
2617
|
progressImport,
|
|
2618
|
+
mediaUploadImport,
|
|
2591
2619
|
zodFields,
|
|
2592
2620
|
defaults,
|
|
2593
2621
|
stepsConst,
|
|
@@ -2615,13 +2643,28 @@ function escapeQuotes(str) {
|
|
|
2615
2643
|
return str.replace(/'/g, "\\'");
|
|
2616
2644
|
}
|
|
2617
2645
|
function buildComponentSource(p7) {
|
|
2646
|
+
const queryClientImport = p7.hasFileUpload ? `
|
|
2647
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'` : "";
|
|
2648
|
+
const queryClientSetup = p7.hasFileUpload ? `
|
|
2649
|
+
const queryClient = new QueryClient()
|
|
2650
|
+
` : "";
|
|
2651
|
+
const formComponentDecl = p7.hasFileUpload ? `function ${p7.pascal}FormInner` : `export function ${p7.pascal}Form`;
|
|
2652
|
+
const exportWrapper = p7.hasFileUpload ? `
|
|
2653
|
+
export function ${p7.pascal}Form() {
|
|
2654
|
+
return (
|
|
2655
|
+
<QueryClientProvider client={queryClient}>
|
|
2656
|
+
<${p7.pascal}FormInner />
|
|
2657
|
+
</QueryClientProvider>
|
|
2658
|
+
)
|
|
2659
|
+
}
|
|
2660
|
+
` : "";
|
|
2618
2661
|
return `'use client'
|
|
2619
2662
|
|
|
2620
2663
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
2621
2664
|
import { Check, ChevronLeft, ChevronRight } from 'lucide-react'
|
|
2622
2665
|
import { useState } from 'react'
|
|
2623
2666
|
${p7.rhfImport}
|
|
2624
|
-
import { z } from 'zod/v3'
|
|
2667
|
+
import { z } from 'zod/v3'${queryClientImport}
|
|
2625
2668
|
import { create${p7.pascal}Submission } from '@cms/actions/${p7.kebab}-form'
|
|
2626
2669
|
import { Button } from '${p7.buttonImport}'
|
|
2627
2670
|
import {
|
|
@@ -2633,7 +2676,8 @@ import {
|
|
|
2633
2676
|
FormLabel,
|
|
2634
2677
|
FormMessage,
|
|
2635
2678
|
} from '${p7.formImport}'
|
|
2636
|
-
import { Input } from '${p7.inputImport}'
|
|
2679
|
+
import { Input } from '${p7.inputImport}'${p7.hasFileUpload ? `
|
|
2680
|
+
import { MediaUploadField } from '${p7.mediaUploadImport}'` : ""}
|
|
2637
2681
|
import { Progress } from '${p7.progressImport}'${p7.hasRadio ? `
|
|
2638
2682
|
import { RadioGroup, RadioGroupItem } from '${p7.radioGroupImport}'` : ""}
|
|
2639
2683
|
import { Textarea } from '${p7.textareaImport}'
|
|
@@ -2650,10 +2694,10 @@ ${p7.zodFields}
|
|
|
2650
2694
|
})
|
|
2651
2695
|
|
|
2652
2696
|
type FormValues = z.infer<typeof formSchema>
|
|
2653
|
-
|
|
2697
|
+
${queryClientSetup}
|
|
2654
2698
|
${p7.stepsConst}
|
|
2655
2699
|
|
|
2656
|
-
|
|
2700
|
+
${formComponentDecl}() {
|
|
2657
2701
|
const [currentStep, setCurrentStep] = useState(0)
|
|
2658
2702
|
const [completedSteps, setCompletedSteps] = useState<Set<number>>(new Set())
|
|
2659
2703
|
const [submitted, setSubmitted] = useState(false)
|
|
@@ -2800,7 +2844,7 @@ ${p7.stepContentBlocks}
|
|
|
2800
2844
|
</Form>
|
|
2801
2845
|
)
|
|
2802
2846
|
}
|
|
2803
|
-
`;
|
|
2847
|
+
${exportWrapper}`;
|
|
2804
2848
|
}
|
|
2805
2849
|
|
|
2806
2850
|
// src/generators/form-pipeline/form-component-single.ts
|
|
@@ -2831,18 +2875,35 @@ function generateSingleStepForm(schema, cwd, cmsDir, options) {
|
|
|
2831
2875
|
${buildFieldArrayDecls(listFields)}
|
|
2832
2876
|
` : "";
|
|
2833
2877
|
const hasRadio = fields.some((f) => f.type === "radio");
|
|
2878
|
+
const hasFileUpload = fields.some((f) => f.type === "file" || f.type === "upload");
|
|
2834
2879
|
const buttonImport = resolveUiImport(cwd, "button");
|
|
2835
2880
|
const formImport = resolveUiImport(cwd, "form");
|
|
2836
2881
|
const inputImport = resolveUiImport(cwd, "input");
|
|
2837
2882
|
const textareaImport = resolveUiImport(cwd, "textarea");
|
|
2838
2883
|
const selectImport = resolveUiImport(cwd, "select");
|
|
2839
2884
|
const radioGroupImport = resolveUiImport(cwd, "radio-group");
|
|
2885
|
+
const mediaUploadImport = resolveUiImport(cwd, "media-upload-field");
|
|
2886
|
+
const queryClientImport = hasFileUpload ? `
|
|
2887
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'` : "";
|
|
2888
|
+
const queryClientSetup = hasFileUpload ? `
|
|
2889
|
+
const queryClient = new QueryClient()
|
|
2890
|
+
` : "";
|
|
2891
|
+
const formComponentDecl = hasFileUpload ? `function ${pascal}FormInner` : `export function ${pascal}Form`;
|
|
2892
|
+
const exportWrapper = hasFileUpload ? `
|
|
2893
|
+
export function ${pascal}Form() {
|
|
2894
|
+
return (
|
|
2895
|
+
<QueryClientProvider client={queryClient}>
|
|
2896
|
+
<${pascal}FormInner />
|
|
2897
|
+
</QueryClientProvider>
|
|
2898
|
+
)
|
|
2899
|
+
}
|
|
2900
|
+
` : "";
|
|
2840
2901
|
const content = `'use client'
|
|
2841
2902
|
|
|
2842
2903
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
2843
2904
|
import { useState } from 'react'
|
|
2844
2905
|
${rhfImport}
|
|
2845
|
-
import { z } from 'zod/v3'
|
|
2906
|
+
import { z } from 'zod/v3'${queryClientImport}
|
|
2846
2907
|
import { create${pascal}Submission } from '@cms/actions/${kebab}-form'
|
|
2847
2908
|
import { Button } from '${buttonImport}'
|
|
2848
2909
|
import {
|
|
@@ -2854,7 +2915,8 @@ import {
|
|
|
2854
2915
|
FormLabel,
|
|
2855
2916
|
FormMessage,
|
|
2856
2917
|
} from '${formImport}'
|
|
2857
|
-
import { Input } from '${inputImport}'${
|
|
2918
|
+
import { Input } from '${inputImport}'${hasFileUpload ? `
|
|
2919
|
+
import { MediaUploadField } from '${mediaUploadImport}'` : ""}${hasRadio ? `
|
|
2858
2920
|
import { RadioGroup, RadioGroupItem } from '${radioGroupImport}'` : ""}
|
|
2859
2921
|
import { Textarea } from '${textareaImport}'
|
|
2860
2922
|
import {
|
|
@@ -2870,8 +2932,8 @@ ${zodFields}
|
|
|
2870
2932
|
})
|
|
2871
2933
|
|
|
2872
2934
|
type FormValues = z.infer<typeof formSchema>
|
|
2873
|
-
|
|
2874
|
-
|
|
2935
|
+
${queryClientSetup}
|
|
2936
|
+
${formComponentDecl}() {
|
|
2875
2937
|
const [submitted, setSubmitted] = useState(false)
|
|
2876
2938
|
const [submitting, setSubmitting] = useState(false)
|
|
2877
2939
|
|
|
@@ -2923,7 +2985,7 @@ ${fieldJSX}
|
|
|
2923
2985
|
</Form>
|
|
2924
2986
|
)
|
|
2925
2987
|
}
|
|
2926
|
-
`;
|
|
2988
|
+
${exportWrapper}`;
|
|
2927
2989
|
fs9.writeFileSync(filePath, content, "utf-8");
|
|
2928
2990
|
return { files: [path9.relative(cwd, filePath)] };
|
|
2929
2991
|
}
|