@saastro/forms 0.1.3

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.
@@ -0,0 +1,139 @@
1
+ import {
2
+ MissingComponentFallback,
3
+ useComponents
4
+ } from "./chunk-GHDCNAWC.js";
5
+
6
+ // src/factory/DateRenderers.tsx
7
+ import { ChevronDown } from "lucide-react";
8
+ import React from "react";
9
+ import { format } from "date-fns";
10
+ import { es } from "date-fns/locale";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ var DateRenderers = ({
13
+ type = "simple",
14
+ value,
15
+ onChange,
16
+ disabled,
17
+ className,
18
+ label = "date",
19
+ placeholder = "Seleccionar fecha"
20
+ }) => {
21
+ const components = useComponents();
22
+ const { Button, Calendar, Popover, PopoverTrigger, PopoverContent } = components;
23
+ const [open, setOpen] = React.useState(false);
24
+ const getMissingComponents = () => {
25
+ const missing = [];
26
+ if (!Calendar) missing.push("Calendar");
27
+ if (type !== "simple") {
28
+ if (!Button) missing.push("Button");
29
+ if (!Popover) missing.push("Popover");
30
+ if (!PopoverTrigger) missing.push("PopoverTrigger");
31
+ if (!PopoverContent) missing.push("PopoverContent");
32
+ }
33
+ return missing;
34
+ };
35
+ const missingComponents = getMissingComponents();
36
+ if (missingComponents.length > 0) {
37
+ return /* @__PURE__ */ jsx(
38
+ MissingComponentFallback,
39
+ {
40
+ fieldName: label,
41
+ fieldType: type === "range" ? "daterange" : "date",
42
+ missingComponents
43
+ }
44
+ );
45
+ }
46
+ switch (type) {
47
+ case "simple":
48
+ return /* @__PURE__ */ jsx(
49
+ Calendar,
50
+ {
51
+ mode: "single",
52
+ selected: value,
53
+ onSelect: onChange,
54
+ disabled,
55
+ className,
56
+ buttonVariant: "ghost"
57
+ }
58
+ );
59
+ case "popover":
60
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
61
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
62
+ Button,
63
+ {
64
+ variant: "outline",
65
+ className: "w-full justify-between font-normal",
66
+ disabled,
67
+ children: [
68
+ value ? format(value, "PPP", { locale: es }) : placeholder,
69
+ /* @__PURE__ */ jsx(ChevronDown, { className: "ml-2 h-4 w-4 opacity-50" })
70
+ ]
71
+ }
72
+ ) }),
73
+ /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx(
74
+ Calendar,
75
+ {
76
+ mode: "single",
77
+ selected: value,
78
+ captionLayout: "dropdown",
79
+ onSelect: (date) => {
80
+ onChange?.(date);
81
+ setOpen(false);
82
+ },
83
+ disabled,
84
+ className: "rounded-md border"
85
+ }
86
+ ) })
87
+ ] }) });
88
+ case "range": {
89
+ const rangeValue = value;
90
+ const formatRange = (range) => {
91
+ if (!range?.from) return placeholder;
92
+ if (range.from && !range.to) {
93
+ return `Desde ${format(range.from, "PPP", { locale: es })}`;
94
+ }
95
+ if (range.from && range.to) {
96
+ return `${format(range.from, "PPP", { locale: es })} - ${format(range.to, "PPP", { locale: es })}`;
97
+ }
98
+ return placeholder;
99
+ };
100
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
101
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
102
+ Button,
103
+ {
104
+ variant: "outline",
105
+ className: "w-full justify-between font-normal",
106
+ disabled,
107
+ children: [
108
+ formatRange(rangeValue),
109
+ /* @__PURE__ */ jsx(ChevronDown, { className: "ml-2 h-4 w-4 opacity-50" })
110
+ ]
111
+ }
112
+ ) }),
113
+ /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx(
114
+ Calendar,
115
+ {
116
+ mode: "range",
117
+ selected: rangeValue,
118
+ captionLayout: "dropdown",
119
+ onSelect: (range) => {
120
+ onChange?.(range);
121
+ if (range?.from && range?.to) {
122
+ setOpen(false);
123
+ }
124
+ },
125
+ disabled,
126
+ className: "rounded-md border",
127
+ numberOfMonths: 2
128
+ }
129
+ ) })
130
+ ] }) });
131
+ }
132
+ default:
133
+ return null;
134
+ }
135
+ };
136
+ export {
137
+ DateRenderers
138
+ };
139
+ //# sourceMappingURL=DateRenderers-3JUQNLKJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/factory/DateRenderers.tsx"],"sourcesContent":["import { ChevronDown } from 'lucide-react';\nimport React from 'react';\nimport { useComponents } from '../context/ComponentContext';\nimport { MissingComponentFallback } from '../components/MissingComponentFallback';\n\nimport { format } from 'date-fns';\nimport { es } from 'date-fns/locale';\nimport type { DateRange } from 'react-day-picker';\n\ninterface DateRenderersProps {\n type: 'simple' | 'popover' | 'range';\n value?: Date | DateRange;\n onChange?: (date: Date | DateRange | undefined) => void;\n disabled?: boolean;\n readOnly?: boolean;\n className?: string;\n label?: string;\n placeholder?: string;\n showTime?: boolean;\n presets?: Array<{ label: string; value: number }>;\n}\n\nexport const DateRenderers: React.FC<DateRenderersProps> = ({\n type = 'simple',\n value,\n onChange,\n disabled,\n className,\n label = 'date',\n placeholder = 'Seleccionar fecha',\n}) => {\n const components = useComponents();\n const { Button, Calendar, Popover, PopoverTrigger, PopoverContent } = components;\n const [open, setOpen] = React.useState(false);\n\n // Check for missing components based on type\n const getMissingComponents = (): string[] => {\n const missing: string[] = [];\n if (!Calendar) missing.push('Calendar');\n if (type !== 'simple') {\n if (!Button) missing.push('Button');\n if (!Popover) missing.push('Popover');\n if (!PopoverTrigger) missing.push('PopoverTrigger');\n if (!PopoverContent) missing.push('PopoverContent');\n }\n return missing;\n };\n\n const missingComponents = getMissingComponents();\n if (missingComponents.length > 0) {\n return (\n <MissingComponentFallback\n fieldName={label}\n fieldType={type === 'range' ? 'daterange' : 'date'}\n missingComponents={missingComponents}\n />\n );\n }\n\n switch (type) {\n case 'simple':\n return (\n <Calendar\n mode=\"single\"\n selected={value as Date}\n onSelect={onChange as (date: Date | undefined) => void}\n disabled={disabled}\n className={className}\n buttonVariant=\"ghost\"\n />\n );\n\n case 'popover':\n return (\n <div className=\"flex flex-col gap-3\">\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n className=\"w-full justify-between font-normal\"\n disabled={disabled}\n >\n {value ? format(value as Date, 'PPP', { locale: es }) : placeholder}\n <ChevronDown className=\"ml-2 h-4 w-4 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={value as Date}\n captionLayout=\"dropdown\"\n onSelect={(date: Date | undefined) => {\n onChange?.(date);\n setOpen(false);\n }}\n disabled={disabled}\n className=\"rounded-md border\"\n />\n </PopoverContent>\n </Popover>\n </div>\n );\n\n case 'range': {\n const rangeValue = value as DateRange | undefined;\n const formatRange = (range: DateRange | undefined): string => {\n if (!range?.from) return placeholder;\n if (range.from && !range.to) {\n return `Desde ${format(range.from, 'PPP', { locale: es })}`;\n }\n if (range.from && range.to) {\n return `${format(range.from, 'PPP', { locale: es })} - ${format(range.to, 'PPP', { locale: es })}`;\n }\n return placeholder;\n };\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n className=\"w-full justify-between font-normal\"\n disabled={disabled}\n >\n {formatRange(rangeValue)}\n <ChevronDown className=\"ml-2 h-4 w-4 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"range\"\n selected={rangeValue}\n captionLayout=\"dropdown\"\n onSelect={(range: DateRange | undefined) => {\n onChange?.(range);\n if (range?.from && range?.to) {\n setOpen(false);\n }\n }}\n disabled={disabled}\n className=\"rounded-md border\"\n numberOfMonths={2}\n />\n </PopoverContent>\n </Popover>\n </div>\n );\n }\n\n default:\n return null;\n }\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,247 @@
1
+ // src/context/ComponentContext.tsx
2
+ import { createContext, useContext, useMemo } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var ComponentContext = createContext(null);
5
+ var InternalComponentContext = createContext(null);
6
+ var ComponentProvider = ({ components, children }) => {
7
+ return /* @__PURE__ */ jsx(ComponentContext.Provider, { value: components, children });
8
+ };
9
+ var InternalComponentProvider = ({
10
+ components,
11
+ children
12
+ }) => {
13
+ return /* @__PURE__ */ jsx(InternalComponentContext.Provider, { value: components, children });
14
+ };
15
+ var useComponents = () => {
16
+ const legacyComponents = useContext(ComponentContext);
17
+ const internalComponents = useContext(InternalComponentContext);
18
+ if (legacyComponents) {
19
+ return legacyComponents;
20
+ }
21
+ if (internalComponents) {
22
+ return internalComponents;
23
+ }
24
+ throw new Error(
25
+ "useComponents must be used within a Form component or ComponentProvider.\n\nOption 1 (Recommended - Zero Config):\n <Form config={config} components={{ Input, Button }} />\n\nOption 2 (Legacy):\n <ComponentProvider components={fullRegistry}>\n <Form config={config} />\n </ComponentProvider>\n\nSee documentation: https://forms.saastro.io/getting-started"
26
+ );
27
+ };
28
+ var usePartialComponents = () => {
29
+ const legacyComponents = useContext(ComponentContext);
30
+ const internalComponents = useContext(InternalComponentContext);
31
+ if (legacyComponents) {
32
+ return legacyComponents;
33
+ }
34
+ if (internalComponents) {
35
+ return internalComponents;
36
+ }
37
+ return {};
38
+ };
39
+ function withComponents(Component) {
40
+ const WrappedComponent = (props) => {
41
+ const components = useComponents();
42
+ return /* @__PURE__ */ jsx(Component, { ...props, components });
43
+ };
44
+ WrappedComponent.displayName = `withComponents(${Component.displayName || Component.name || "Component"})`;
45
+ return WrappedComponent;
46
+ }
47
+ var useHasComponentProvider = () => {
48
+ const legacyComponents = useContext(ComponentContext);
49
+ const internalComponents = useContext(InternalComponentContext);
50
+ return legacyComponents !== null || internalComponents !== null;
51
+ };
52
+ var useComponentMode = () => {
53
+ const legacyComponents = useContext(ComponentContext);
54
+ const internalComponents = useContext(InternalComponentContext);
55
+ if (legacyComponents) return "legacy";
56
+ if (internalComponents) return "zero-config";
57
+ return "none";
58
+ };
59
+ function mergeComponentRegistries(...registries) {
60
+ const result = {};
61
+ for (const registry of registries) {
62
+ if (registry) {
63
+ for (const [key, value] of Object.entries(registry)) {
64
+ if (value !== void 0) {
65
+ result[key] = value;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ return result;
71
+ }
72
+ function pathToComponentName(path) {
73
+ const filename = path.split("/").pop()?.replace(/\.(tsx?|jsx?)$/, "") || "";
74
+ const specialCases = {
75
+ "input-otp": "InputOTP",
76
+ otp: "OTP"
77
+ };
78
+ if (specialCases[filename]) {
79
+ return specialCases[filename];
80
+ }
81
+ return filename.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
82
+ }
83
+ function parseGlobModules(modules) {
84
+ const registry = {};
85
+ for (const [path, mod] of Object.entries(modules)) {
86
+ if (typeof mod !== "object" || mod === null) continue;
87
+ const baseName = pathToComponentName(path);
88
+ for (const [exportName, exportValue] of Object.entries(mod)) {
89
+ if (typeof exportValue === "function" || typeof exportValue === "object" && exportValue !== null && "$$typeof" in exportValue) {
90
+ if (exportName !== "default") {
91
+ registry[exportName] = exportValue;
92
+ } else {
93
+ registry[baseName] = exportValue;
94
+ }
95
+ }
96
+ }
97
+ }
98
+ return registry;
99
+ }
100
+ var FormComponentsProvider = ({
101
+ components: globModules,
102
+ children
103
+ }) => {
104
+ const registry = useMemo(() => parseGlobModules(globModules), [globModules]);
105
+ return /* @__PURE__ */ jsx(InternalComponentContext.Provider, { value: registry, children });
106
+ };
107
+
108
+ // src/components/MissingComponentFallback.tsx
109
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
110
+ function getInstallCommand(missingComponents) {
111
+ const packageMap = {
112
+ Input: "input",
113
+ Textarea: "textarea",
114
+ Button: "button",
115
+ Label: "label",
116
+ Checkbox: "checkbox",
117
+ Switch: "switch",
118
+ RadioGroup: "radio-group",
119
+ RadioGroupItem: "radio-group",
120
+ Select: "select",
121
+ SelectTrigger: "select",
122
+ SelectContent: "select",
123
+ SelectItem: "select",
124
+ SelectValue: "select",
125
+ NativeSelect: "native-select",
126
+ Slider: "slider",
127
+ Popover: "popover",
128
+ PopoverTrigger: "popover",
129
+ PopoverContent: "popover",
130
+ Tooltip: "tooltip",
131
+ TooltipTrigger: "tooltip",
132
+ TooltipContent: "tooltip",
133
+ TooltipProvider: "tooltip",
134
+ Separator: "separator",
135
+ Dialog: "dialog",
136
+ DialogTrigger: "dialog",
137
+ DialogContent: "dialog",
138
+ DialogHeader: "dialog",
139
+ DialogTitle: "dialog",
140
+ DialogDescription: "dialog",
141
+ Command: "command",
142
+ CommandInput: "command",
143
+ CommandList: "command",
144
+ CommandEmpty: "command",
145
+ CommandGroup: "command",
146
+ CommandItem: "command",
147
+ InputOTP: "input-otp",
148
+ InputOTPGroup: "input-otp",
149
+ InputOTPSlot: "input-otp",
150
+ Accordion: "accordion",
151
+ AccordionItem: "accordion",
152
+ AccordionTrigger: "accordion",
153
+ AccordionContent: "accordion",
154
+ Calendar: "calendar",
155
+ FormField: "form",
156
+ FormControl: "form",
157
+ Field: "field",
158
+ FieldLabel: "field",
159
+ FieldDescription: "field",
160
+ FieldError: "field"
161
+ };
162
+ const packages = /* @__PURE__ */ new Set();
163
+ for (const component of missingComponents) {
164
+ const pkg = packageMap[component];
165
+ if (pkg) {
166
+ packages.add(pkg);
167
+ }
168
+ }
169
+ const packageList = Array.from(packages).join(" ");
170
+ return `npx shadcn@latest add ${packageList}`;
171
+ }
172
+ function MissingComponentFallback({
173
+ fieldName,
174
+ fieldType,
175
+ missingComponents,
176
+ message,
177
+ className
178
+ }) {
179
+ const installCmd = getInstallCommand(missingComponents);
180
+ return /* @__PURE__ */ jsx2(
181
+ "div",
182
+ {
183
+ className: `border-2 border-dashed border-amber-400 bg-amber-50 dark:bg-amber-950/20 rounded-lg p-4 my-2 ${className || ""}`,
184
+ role: "alert",
185
+ "aria-live": "polite",
186
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
187
+ /* @__PURE__ */ jsx2(
188
+ "span",
189
+ {
190
+ className: "text-amber-600 dark:text-amber-400 text-xl flex-shrink-0",
191
+ "aria-hidden": "true",
192
+ children: "\u26A0\uFE0F"
193
+ }
194
+ ),
195
+ /* @__PURE__ */ jsxs("div", { className: "text-sm min-w-0", children: [
196
+ /* @__PURE__ */ jsx2("p", { className: "font-medium text-amber-800 dark:text-amber-200", children: message || /* @__PURE__ */ jsxs(Fragment, { children: [
197
+ 'Field "',
198
+ fieldName,
199
+ '" (',
200
+ fieldType,
201
+ ") requires missing components:"
202
+ ] }) }),
203
+ /* @__PURE__ */ jsx2("code", { className: "block mt-1 text-amber-700 dark:text-amber-300 break-words", children: missingComponents.join(", ") }),
204
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 bg-amber-100 dark:bg-amber-900/30 rounded px-3 py-2 overflow-x-auto", children: [
205
+ /* @__PURE__ */ jsx2("p", { className: "text-xs text-amber-600 dark:text-amber-400 mb-1", children: "Install with:" }),
206
+ /* @__PURE__ */ jsx2("code", { className: "text-xs font-mono text-amber-800 dark:text-amber-200 whitespace-nowrap", children: installCmd })
207
+ ] }),
208
+ /* @__PURE__ */ jsxs("p", { className: "mt-2 text-xs text-amber-600 dark:text-amber-400", children: [
209
+ "Or provide components via the",
210
+ " ",
211
+ /* @__PURE__ */ jsx2("code", { className: "bg-amber-100 dark:bg-amber-900/50 px-1 rounded", children: "components" }),
212
+ " prop:"
213
+ ] }),
214
+ /* @__PURE__ */ jsx2("pre", { className: "mt-1 text-xs bg-amber-100 dark:bg-amber-900/30 rounded px-2 py-1 overflow-x-auto", children: /* @__PURE__ */ jsx2("code", { children: `<Form config={config} components={{ ${missingComponents[0]}: MyCustom${missingComponents[0]} }} />` }) })
215
+ ] })
216
+ ] })
217
+ }
218
+ );
219
+ }
220
+ function createMissingComponentPlaceholder(componentName, fieldType) {
221
+ const Placeholder = ({ name = "unknown" }) => /* @__PURE__ */ jsx2(
222
+ MissingComponentFallback,
223
+ {
224
+ fieldName: name,
225
+ fieldType,
226
+ missingComponents: [componentName]
227
+ }
228
+ );
229
+ Placeholder.displayName = `Missing${componentName}`;
230
+ return Placeholder;
231
+ }
232
+
233
+ export {
234
+ ComponentProvider,
235
+ InternalComponentProvider,
236
+ useComponents,
237
+ usePartialComponents,
238
+ withComponents,
239
+ useHasComponentProvider,
240
+ useComponentMode,
241
+ mergeComponentRegistries,
242
+ parseGlobModules,
243
+ FormComponentsProvider,
244
+ MissingComponentFallback,
245
+ createMissingComponentPlaceholder
246
+ };
247
+ //# sourceMappingURL=chunk-GHDCNAWC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/context/ComponentContext.tsx","../src/components/MissingComponentFallback.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from 'react';\nimport type { ComponentRegistry, PartialComponentRegistry } from '../types/components';\n\n/**\n * ============================================\n * COMPONENT CONTEXT - Dependency Injection\n * ============================================\n *\n * Este contexto permite inyectar componentes UI en el plugin,\n * haciendo que sea agnóstico de la librería UI utilizada.\n *\n * Supports two modes:\n * 1. Legacy mode: Full ComponentRegistry via ComponentProvider (required all components)\n * 2. Zero-config mode: Partial registry via InternalComponentContext (Form-level)\n */\n\n// Legacy context for full registry (backwards compatible)\nconst ComponentContext = createContext<ComponentRegistry | null>(null);\n\n// Internal context for Form-level partial registry (zero-config mode)\nconst InternalComponentContext = createContext<PartialComponentRegistry | null>(null);\n\nexport interface ComponentProviderProps {\n /** Registry completo de componentes UI */\n components: ComponentRegistry;\n /** Componentes hijos que tendrán acceso al registry */\n children: React.ReactNode;\n}\n\n/**\n * Provider que inyecta los componentes UI en el árbol de React.\n * This is the legacy provider that requires a full ComponentRegistry.\n *\n * @example\n * ```tsx\n * import { ComponentProvider, createComponentRegistry } from \"@saastro/forms\";\n * import * as shadcn from \"@/lib/form-components\";\n *\n * const registry = createComponentRegistry(shadcn);\n *\n * function App() {\n * return (\n * <ComponentProvider components={registry}>\n * <MyForm />\n * </ComponentProvider>\n * );\n * }\n * ```\n *\n * @deprecated Consider using the zero-config approach with inline components prop on Form\n */\nexport const ComponentProvider: React.FC<ComponentProviderProps> = ({ components, children }) => {\n return <ComponentContext.Provider value={components}>{children}</ComponentContext.Provider>;\n};\n\nexport interface InternalComponentProviderProps {\n /** Partial registry de componentes UI */\n components: PartialComponentRegistry;\n /** Componentes hijos que tendrán acceso al registry */\n children: React.ReactNode;\n}\n\n/**\n * Internal provider used by Form component for zero-config mode.\n * Accepts a partial registry - only the components needed for the form.\n *\n * @internal\n */\nexport const InternalComponentProvider: React.FC<InternalComponentProviderProps> = ({\n components,\n children,\n}) => {\n return (\n <InternalComponentContext.Provider value={components}>\n {children}\n </InternalComponentContext.Provider>\n );\n};\n\n/**\n * Hook para acceder al registry de componentes inyectados.\n *\n * Supports both legacy (ComponentProvider) and zero-config (InternalComponentContext) modes.\n * Legacy mode takes precedence for backwards compatibility.\n *\n * @throws Error si se usa fuera de cualquier provider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { Input, Button } = useComponents();\n *\n * return (\n * <div>\n * <Input placeholder=\"Email\" />\n * <Button>Submit</Button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useComponents = (): ComponentRegistry => {\n const legacyComponents = useContext(ComponentContext);\n const internalComponents = useContext(InternalComponentContext);\n\n // Legacy mode takes precedence\n if (legacyComponents) {\n return legacyComponents;\n }\n\n // Zero-config mode\n if (internalComponents) {\n // Return partial as full (consumers should handle missing components)\n return internalComponents as ComponentRegistry;\n }\n\n throw new Error(\n 'useComponents must be used within a Form component or ComponentProvider.\\n\\n' +\n 'Option 1 (Recommended - Zero Config):\\n' +\n ' <Form config={config} components={{ Input, Button }} />\\n\\n' +\n 'Option 2 (Legacy):\\n' +\n ' <ComponentProvider components={fullRegistry}>\\n' +\n ' <Form config={config} />\\n' +\n ' </ComponentProvider>\\n\\n' +\n 'See documentation: https://forms.saastro.io/getting-started',\n );\n};\n\n/**\n * Hook to access partial components safely (may have missing components).\n * Returns null for components that are not provided.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const components = usePartialComponents();\n *\n * if (!components.Input) {\n * return <MissingComponentFallback missingComponents={['Input']} />;\n * }\n *\n * return <components.Input placeholder=\"Email\" />;\n * }\n * ```\n */\nexport const usePartialComponents = (): PartialComponentRegistry => {\n const legacyComponents = useContext(ComponentContext);\n const internalComponents = useContext(InternalComponentContext);\n\n if (legacyComponents) {\n return legacyComponents;\n }\n\n if (internalComponents) {\n return internalComponents;\n }\n\n return {};\n};\n\n/**\n * HOC para envolver componentes que necesitan acceso a los componentes UI.\n *\n * @example\n * ```tsx\n * const MyFormWithComponents = withComponents(MyForm);\n * ```\n */\nexport function withComponents<P extends object>(Component: React.ComponentType<P>): React.FC<P> {\n const WrappedComponent: React.FC<P> = (props) => {\n const components = useComponents();\n return <Component {...props} components={components} />;\n };\n\n WrappedComponent.displayName = `withComponents(${Component.displayName || Component.name || 'Component'})`;\n\n return WrappedComponent;\n}\n\n/**\n * Hook para verificar si estamos dentro de un ComponentProvider.\n * Útil para componentes que pueden funcionar con o sin provider.\n *\n * @returns true si hay un provider activo (legacy or internal), false en caso contrario\n */\nexport const useHasComponentProvider = (): boolean => {\n const legacyComponents = useContext(ComponentContext);\n const internalComponents = useContext(InternalComponentContext);\n return legacyComponents !== null || internalComponents !== null;\n};\n\n/**\n * Hook to check which mode we're operating in\n */\nexport const useComponentMode = (): 'legacy' | 'zero-config' | 'none' => {\n const legacyComponents = useContext(ComponentContext);\n const internalComponents = useContext(InternalComponentContext);\n\n if (legacyComponents) return 'legacy';\n if (internalComponents) return 'zero-config';\n return 'none';\n};\n\n/**\n * Merge multiple component registries with later ones taking precedence\n */\nexport function mergeComponentRegistries(\n ...registries: Array<PartialComponentRegistry | undefined>\n): PartialComponentRegistry {\n const result: PartialComponentRegistry = {};\n\n for (const registry of registries) {\n if (registry) {\n for (const [key, value] of Object.entries(registry)) {\n if (value !== undefined) {\n (result as Record<string, unknown>)[key] = value;\n }\n }\n }\n }\n\n return result;\n}\n\n// ═══════════════════════════════════════════════════════════\n// GLOB-BASED AUTO-DISCOVERY (Recommended for Vite projects)\n// ═══════════════════════════════════════════════════════════\n\n/**\n * Type for Vite's import.meta.glob result.\n * Accepts the actual Vite return type which is Record<string, unknown>.\n */\nexport type GlobModules = Record<string, unknown>;\n\n/**\n * Convert a file path to PascalCase component name\n * @example\n * '/components/ui/button.tsx' -> 'Button'\n * '/components/ui/radio-group.tsx' -> 'RadioGroup'\n * '/components/ui/input-otp.tsx' -> 'InputOTP'\n */\nfunction pathToComponentName(path: string): string {\n // Extract filename without extension\n const filename =\n path\n .split('/')\n .pop()\n ?.replace(/\\.(tsx?|jsx?)$/, '') || '';\n\n // Special cases for common naming patterns\n const specialCases: Record<string, string> = {\n 'input-otp': 'InputOTP',\n otp: 'OTP',\n };\n\n if (specialCases[filename]) {\n return specialCases[filename];\n }\n\n // Convert kebab-case to PascalCase\n return filename\n .split('-')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\n/**\n * Parse Vite's import.meta.glob result into a component registry.\n *\n * This function extracts all named exports from the glob modules\n * and creates a flat registry of components.\n *\n * @param modules - Result of import.meta.glob('@/components/ui/*.tsx', { eager: true })\n * @returns Component registry ready to use with Form\n *\n * @example\n * ```tsx\n * const modules = import.meta.glob('@/components/ui/*.tsx', { eager: true });\n * const components = parseGlobModules(modules);\n * // { Button, Input, Label, Select, SelectTrigger, ... }\n * ```\n */\nexport function parseGlobModules(modules: GlobModules): PartialComponentRegistry {\n const registry: Record<string, React.ComponentType<unknown>> = {};\n\n for (const [path, mod] of Object.entries(modules)) {\n // Skip if module is not an object (shouldn't happen with eager: true)\n if (typeof mod !== 'object' || mod === null) continue;\n\n // Get the base component name from file path\n const baseName = pathToComponentName(path);\n\n // Extract all named exports that look like React components\n for (const [exportName, exportValue] of Object.entries(mod as Record<string, unknown>)) {\n // Skip non-component exports (like types, constants, etc.)\n if (\n typeof exportValue === 'function' ||\n (typeof exportValue === 'object' && exportValue !== null && '$$typeof' in exportValue)\n ) {\n // Use the export name directly (Button, SelectTrigger, etc.)\n if (exportName !== 'default') {\n registry[exportName] = exportValue as React.ComponentType<unknown>;\n } else {\n // For default exports, use the file name\n registry[baseName] = exportValue as React.ComponentType<unknown>;\n }\n }\n }\n }\n\n return registry as PartialComponentRegistry;\n}\n\nexport interface FormComponentsProviderProps {\n /**\n * Glob modules from import.meta.glob.\n * Use { eager: true } for synchronous loading.\n *\n * @example\n * ```tsx\n * <FormComponentsProvider\n * components={import.meta.glob('@/components/ui/*.tsx', { eager: true })}\n * >\n * ```\n */\n components: GlobModules;\n /** Child components */\n children: React.ReactNode;\n}\n\n/**\n * Provider for auto-discovered shadcn components using Vite's import.meta.glob.\n *\n * Place this once at your app's root layout. Forms will automatically\n * use any shadcn components installed in your project.\n *\n * @example\n * ```tsx\n * // app/layout.tsx or _app.tsx - ONE TIME SETUP\n * import { FormComponentsProvider } from '@saastro/forms';\n *\n * export default function RootLayout({ children }) {\n * return (\n * <FormComponentsProvider\n * components={import.meta.glob('@/components/ui/*.tsx', { eager: true })}\n * >\n * {children}\n * </FormComponentsProvider>\n * );\n * }\n * ```\n *\n * Then use Form anywhere without passing components:\n * ```tsx\n * <Form config={config} />\n * ```\n *\n * If a component is missing, a helpful message will appear\n * with installation instructions.\n */\nexport const FormComponentsProvider: React.FC<FormComponentsProviderProps> = ({\n components: globModules,\n children,\n}) => {\n // Parse glob modules into component registry (memoized)\n const registry = useMemo(() => parseGlobModules(globModules), [globModules]);\n\n return (\n <InternalComponentContext.Provider value={registry}>\n {children}\n </InternalComponentContext.Provider>\n );\n};\n","import React from 'react';\n\n/**\n * Props for MissingComponentFallback\n */\nexport interface MissingComponentFallbackProps {\n /** Name of the field that requires the missing component */\n fieldName: string;\n /** Type of the field (e.g., 'text', 'select', 'date') */\n fieldType: string;\n /** List of missing component names */\n missingComponents: string[];\n /** Optional custom message */\n message?: string;\n /** Optional className for layout (e.g., column span classes) */\n className?: string;\n}\n\n/**\n * Generates the npx shadcn command for installing missing components\n */\nfunction getInstallCommand(missingComponents: string[]): string {\n // Map component names to their shadcn package names\n const packageMap: Record<string, string> = {\n Input: 'input',\n Textarea: 'textarea',\n Button: 'button',\n Label: 'label',\n Checkbox: 'checkbox',\n Switch: 'switch',\n RadioGroup: 'radio-group',\n RadioGroupItem: 'radio-group',\n Select: 'select',\n SelectTrigger: 'select',\n SelectContent: 'select',\n SelectItem: 'select',\n SelectValue: 'select',\n NativeSelect: 'native-select',\n Slider: 'slider',\n Popover: 'popover',\n PopoverTrigger: 'popover',\n PopoverContent: 'popover',\n Tooltip: 'tooltip',\n TooltipTrigger: 'tooltip',\n TooltipContent: 'tooltip',\n TooltipProvider: 'tooltip',\n Separator: 'separator',\n Dialog: 'dialog',\n DialogTrigger: 'dialog',\n DialogContent: 'dialog',\n DialogHeader: 'dialog',\n DialogTitle: 'dialog',\n DialogDescription: 'dialog',\n Command: 'command',\n CommandInput: 'command',\n CommandList: 'command',\n CommandEmpty: 'command',\n CommandGroup: 'command',\n CommandItem: 'command',\n InputOTP: 'input-otp',\n InputOTPGroup: 'input-otp',\n InputOTPSlot: 'input-otp',\n Accordion: 'accordion',\n AccordionItem: 'accordion',\n AccordionTrigger: 'accordion',\n AccordionContent: 'accordion',\n Calendar: 'calendar',\n FormField: 'form',\n FormControl: 'form',\n Field: 'field',\n FieldLabel: 'field',\n FieldDescription: 'field',\n FieldError: 'field',\n };\n\n // Get unique package names\n const packages = new Set<string>();\n for (const component of missingComponents) {\n const pkg = packageMap[component];\n if (pkg) {\n packages.add(pkg);\n }\n }\n\n const packageList = Array.from(packages).join(' ');\n return `npx shadcn@latest add ${packageList}`;\n}\n\n/**\n * Fallback component displayed when required UI components are missing.\n * Shows a helpful warning with installation instructions.\n *\n * @example\n * ```tsx\n * <MissingComponentFallback\n * fieldName=\"birthdate\"\n * fieldType=\"date\"\n * missingComponents={['Calendar', 'Popover']}\n * />\n * ```\n */\nexport function MissingComponentFallback({\n fieldName,\n fieldType,\n missingComponents,\n message,\n className,\n}: MissingComponentFallbackProps): React.ReactElement {\n const installCmd = getInstallCommand(missingComponents);\n\n return (\n <div\n className={`border-2 border-dashed border-amber-400 bg-amber-50 dark:bg-amber-950/20 rounded-lg p-4 my-2 ${className || ''}`}\n role=\"alert\"\n aria-live=\"polite\"\n >\n <div className=\"flex items-start gap-3\">\n {/* Warning Icon */}\n <span\n className=\"text-amber-600 dark:text-amber-400 text-xl flex-shrink-0\"\n aria-hidden=\"true\"\n >\n ⚠️\n </span>\n\n <div className=\"text-sm min-w-0\">\n {/* Main message */}\n <p className=\"font-medium text-amber-800 dark:text-amber-200\">\n {message || (\n <>\n Field &quot;{fieldName}&quot; ({fieldType}) requires missing components:\n </>\n )}\n </p>\n\n {/* Missing components list */}\n <code className=\"block mt-1 text-amber-700 dark:text-amber-300 break-words\">\n {missingComponents.join(', ')}\n </code>\n\n {/* Install command */}\n <div className=\"mt-3 bg-amber-100 dark:bg-amber-900/30 rounded px-3 py-2 overflow-x-auto\">\n <p className=\"text-xs text-amber-600 dark:text-amber-400 mb-1\">Install with:</p>\n <code className=\"text-xs font-mono text-amber-800 dark:text-amber-200 whitespace-nowrap\">\n {installCmd}\n </code>\n </div>\n\n {/* Alternative: provide components prop */}\n <p className=\"mt-2 text-xs text-amber-600 dark:text-amber-400\">\n Or provide components via the{' '}\n <code className=\"bg-amber-100 dark:bg-amber-900/50 px-1 rounded\">components</code> prop:\n </p>\n <pre className=\"mt-1 text-xs bg-amber-100 dark:bg-amber-900/30 rounded px-2 py-1 overflow-x-auto\">\n <code>{`<Form config={config} components={{ ${missingComponents[0]}: MyCustom${missingComponents[0]} }} />`}</code>\n </pre>\n </div>\n </div>\n </div>\n );\n}\n\n/**\n * Creates a placeholder component that renders the MissingComponentFallback\n * Can be used as a drop-in replacement for missing components\n */\nexport function createMissingComponentPlaceholder(\n componentName: string,\n fieldType: string,\n): React.FC<{ name?: string }> {\n const Placeholder: React.FC<{ name?: string }> = ({ name = 'unknown' }) => (\n <MissingComponentFallback\n fieldName={name}\n fieldType={fieldType}\n missingComponents={[componentName]}\n />\n );\n Placeholder.displayName = `Missing${componentName}`;\n return Placeholder;\n}\n"],"mappings":"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","names":["jsx"]}