UNPKG

askeroo

Version:

A modern CLI prompt library with flow control, history navigation, and conditional prompts

123 lines 4.72 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useMemo } from "react"; import { globalRegistry } from "../core/registry.js"; /** * Wrapper component that transforms flat props into structured format. * * This wrapper transforms flat props into a structured format with: * - `options`: User-provided configuration (label, shortLabel, initialValue, etc.) * - `node`: Library flow node properties (state, flow, isFirstInGroup, etc.) * - `events`: Event handlers (onSubmit, onBack, onHintChange, etc.) * * Note: Auto-submit behavior is now controlled within each plugin component. * Components submit with consistent format: { type: "auto" | "skip" | "programmatic", value?: any } * Regular values (non-objects or objects without type property) are treated as manual submissions */ export function PluginWrapper({ pluginType, promptId, ...props }) { const PluginComponent = globalRegistry.getComponent(pluginType); if (!PluginComponent) { return null; } // Memoize the wrapped onSubmit to prevent unnecessary re-renders const wrappedOnSubmit = useMemo(() => { if (!props.onSubmit) return undefined; const originalOnSubmit = props.onSubmit; const capturedPromptId = promptId; return (value) => { // Check if this is an auto/skip/programmatic submission const isSpecialSubmission = typeof value === "object" && value !== null && "type" in value && (value.type === "auto" || value.type === "skip" || value.type === "programmatic"); if (isSpecialSubmission) { // Get delay from submission object, default to 0ms const delay = typeof value.delay === "number" ? value.delay : 0; // Apply setTimeout with the specified delay // Include the captured prompt ID so handleSubmit knows which prompt this is for setTimeout(() => { originalOnSubmit({ ...value, __promptId: capturedPromptId, }); }, delay); } else { // Regular submission - call immediately originalOnSubmit(value); } }; }, [props.onSubmit, promptId]); // Memoize the wrapped onComplete to automatically use the correct promptId const wrappedOnComplete = useMemo(() => { if (!props.onComplete) return undefined; const originalOnComplete = props.onComplete; const capturedPromptId = promptId; return () => { // Call onComplete with the node's promptId, not whatever the component passes originalOnComplete(capturedPromptId); }; }, [props.onComplete, promptId]); // Transform flat props into structured format const transformedProps = transformPropsToStructure(props, wrappedOnSubmit, wrappedOnComplete); // Handle user's onSubmit callback separately if (props.userOnSubmit) { transformedProps.options.onSubmit = props.userOnSubmit; } // Render plugin component directly return _jsx(PluginComponent, { ...transformedProps }); } /** * Transform flat props into structured format with node, options, and events */ function transformPropsToStructure(props, wrappedOnSubmit, wrappedOnComplete) { // Define known node properties const nodeProps = [ "state", "flow", "isFirstInGroup", "isLastInGroup", "isFirstRootPrompt", "allowBack", "completedValue", "enableArrowNavigation", "depth", "children", ]; // Define known event handlers const eventProps = [ "onBack", "onComplete", "onHintChange", "onValidate", "onNavigate", ]; // Separate props into their categories const node = {}; const events = {}; const options = {}; for (const [key, value] of Object.entries(props)) { if (nodeProps.includes(key)) { node[key] = value; } else if (eventProps.includes(key)) { events[key] = value; } else { options[key] = value; } } // Use the wrapped callbacks if provided (they're already memoized) // Note: wrappedOnSubmit is the internal framework callback, not the user's onSubmit if (wrappedOnSubmit) { events.onSubmit = wrappedOnSubmit; } if (wrappedOnComplete) { events.onComplete = wrappedOnComplete; } return { node, options, events }; } //# sourceMappingURL=PluginWrapper.js.map