@page-speed/forms 0.6.7 → 0.6.8

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.
@@ -604,11 +604,11 @@ interface FormEngineLayoutSettings {
604
604
  /** Settings for the submit button in standard layout */
605
605
  submitButtonSetup?: FormEngineSubmitButtonSetup;
606
606
  }
607
- interface FormEngineProps {
607
+ interface FormEngineSetup {
608
608
  /** API / submission configuration */
609
609
  api?: PageSpeedFormConfig;
610
610
  /** Form field definitions */
611
- fields: FormFieldConfig[];
611
+ fields?: FormFieldConfig[];
612
612
  /** Layout, style, and submit-button settings */
613
613
  formLayoutSettings?: FormEngineLayoutSettings;
614
614
  /** Success message shown after a successful submission */
@@ -636,25 +636,40 @@ interface FormEngineProps {
636
636
  [fileName: string]: number;
637
637
  };
638
638
  }
639
+ interface FormEngineProps extends FormEngineSetup {
640
+ /**
641
+ * Optional wrapper object used by block libraries to pass the full setup as a
642
+ * single prop. Direct props on FormEngine take precedence when both are provided.
643
+ */
644
+ formEngineSetup?: FormEngineSetup;
645
+ /** Default form field definitions used when setup fields are missing/empty */
646
+ defaultFields?: FormFieldConfig[];
647
+ /** Default style rules merged before built-in FormEngine defaults */
648
+ defaultStyleRules?: FormEngineStyleRules;
649
+ }
639
650
  /**
640
651
  * FormEngine — declarative form component with built-in API integration.
641
652
  *
642
- * Handles `useContactForm` orchestration internally so callers only need to
643
- * supply `api`, `fields`, and optional layout/style settings.
653
+ * Handles `useContactForm` orchestration internally so callers can supply
654
+ * either direct props or a `formEngineSetup` wrapper plus optional defaults.
644
655
  *
645
656
  * @example Standard layout
646
657
  * ```tsx
647
658
  * <FormEngine api={api} fields={fields} formLayoutSettings={{ submitButtonSetup: { submitLabel: "Send" } }} />
648
659
  * ```
649
660
  *
650
- * @example Button-group layout
661
+ * @example Wrapped setup with defaults
651
662
  * ```tsx
652
- * <FormEngine api={api} fields={[emailField]} formLayoutSettings={{ formLayout: "button-group", buttonGroupSetup: { size: "lg", submitLabel: "Subscribe" } }} />
663
+ * <FormEngine
664
+ * formEngineSetup={{ api, fields: [emailField] }}
665
+ * defaultFields={fallbackFields}
666
+ * defaultStyleRules={fallbackStyleRules}
667
+ * />
653
668
  * ```
654
669
  */
655
- declare function FormEngine({ api, fields, formLayoutSettings, successMessage, onSubmit, onSuccess, onError, navigate, resetOnSuccess, uploadTokens: externalUploadTokens, onFileUpload: externalOnFileUpload, onFileRemove: externalOnFileRemove, isUploading: externalIsUploading, uploadProgress: externalUploadProgress, }: FormEngineProps): React.JSX.Element;
670
+ declare function FormEngine(props: FormEngineProps): React.JSX.Element;
656
671
  declare namespace FormEngine {
657
672
  var displayName: string;
658
673
  }
659
674
 
660
- export { type AdaptedComponentProps, type Block, type BlockAdapterOptions, type ButtonGroupFormSetup, DynamicFormField, type DynamicFormFieldProps, type FileUploadProgress, FormEngine, type FormEngineLayoutSettings, type FormEngineProps, type FormEngineStyleRules, type FormEngineSubmitButtonSetup, type FormErrors, FormFieldConfig, FormLayoutSettings, type PageSpeedFormConfig, type PageSpeedFormMethod, type PageSpeedFormSubmissionConfig, PageSpeedFormSubmissionError, type PageSpeedFormSubmissionFormat, type PageSpeedFormSubmissionResult, type RailsApiConfig, type RailsErrorResponse, type SerializedFormData, type UseContactFormOptions, type UseContactFormReturn, type UseFileUploadOptions, type UseFileUploadReturn, createBlockAdapter, createBlockAdapters, deserializeErrors, isValidEmail, serializeForRails, standardInputTransformer, submitPageSpeedForm, useContactForm, useFileUpload };
675
+ export { type AdaptedComponentProps, type Block, type BlockAdapterOptions, type ButtonGroupFormSetup, DynamicFormField, type DynamicFormFieldProps, type FileUploadProgress, FormEngine, type FormEngineLayoutSettings, type FormEngineProps, type FormEngineSetup, type FormEngineStyleRules, type FormEngineSubmitButtonSetup, type FormErrors, FormFieldConfig, FormLayoutSettings, type PageSpeedFormConfig, type PageSpeedFormMethod, type PageSpeedFormSubmissionConfig, PageSpeedFormSubmissionError, type PageSpeedFormSubmissionFormat, type PageSpeedFormSubmissionResult, type RailsApiConfig, type RailsErrorResponse, type SerializedFormData, type UseContactFormOptions, type UseContactFormReturn, type UseFileUploadOptions, type UseFileUploadReturn, createBlockAdapter, createBlockAdapters, deserializeErrors, isValidEmail, serializeForRails, standardInputTransformer, submitPageSpeedForm, useContactForm, useFileUpload };
@@ -604,11 +604,11 @@ interface FormEngineLayoutSettings {
604
604
  /** Settings for the submit button in standard layout */
605
605
  submitButtonSetup?: FormEngineSubmitButtonSetup;
606
606
  }
607
- interface FormEngineProps {
607
+ interface FormEngineSetup {
608
608
  /** API / submission configuration */
609
609
  api?: PageSpeedFormConfig;
610
610
  /** Form field definitions */
611
- fields: FormFieldConfig[];
611
+ fields?: FormFieldConfig[];
612
612
  /** Layout, style, and submit-button settings */
613
613
  formLayoutSettings?: FormEngineLayoutSettings;
614
614
  /** Success message shown after a successful submission */
@@ -636,25 +636,40 @@ interface FormEngineProps {
636
636
  [fileName: string]: number;
637
637
  };
638
638
  }
639
+ interface FormEngineProps extends FormEngineSetup {
640
+ /**
641
+ * Optional wrapper object used by block libraries to pass the full setup as a
642
+ * single prop. Direct props on FormEngine take precedence when both are provided.
643
+ */
644
+ formEngineSetup?: FormEngineSetup;
645
+ /** Default form field definitions used when setup fields are missing/empty */
646
+ defaultFields?: FormFieldConfig[];
647
+ /** Default style rules merged before built-in FormEngine defaults */
648
+ defaultStyleRules?: FormEngineStyleRules;
649
+ }
639
650
  /**
640
651
  * FormEngine — declarative form component with built-in API integration.
641
652
  *
642
- * Handles `useContactForm` orchestration internally so callers only need to
643
- * supply `api`, `fields`, and optional layout/style settings.
653
+ * Handles `useContactForm` orchestration internally so callers can supply
654
+ * either direct props or a `formEngineSetup` wrapper plus optional defaults.
644
655
  *
645
656
  * @example Standard layout
646
657
  * ```tsx
647
658
  * <FormEngine api={api} fields={fields} formLayoutSettings={{ submitButtonSetup: { submitLabel: "Send" } }} />
648
659
  * ```
649
660
  *
650
- * @example Button-group layout
661
+ * @example Wrapped setup with defaults
651
662
  * ```tsx
652
- * <FormEngine api={api} fields={[emailField]} formLayoutSettings={{ formLayout: "button-group", buttonGroupSetup: { size: "lg", submitLabel: "Subscribe" } }} />
663
+ * <FormEngine
664
+ * formEngineSetup={{ api, fields: [emailField] }}
665
+ * defaultFields={fallbackFields}
666
+ * defaultStyleRules={fallbackStyleRules}
667
+ * />
653
668
  * ```
654
669
  */
655
- declare function FormEngine({ api, fields, formLayoutSettings, successMessage, onSubmit, onSuccess, onError, navigate, resetOnSuccess, uploadTokens: externalUploadTokens, onFileUpload: externalOnFileUpload, onFileRemove: externalOnFileRemove, isUploading: externalIsUploading, uploadProgress: externalUploadProgress, }: FormEngineProps): React.JSX.Element;
670
+ declare function FormEngine(props: FormEngineProps): React.JSX.Element;
656
671
  declare namespace FormEngine {
657
672
  var displayName: string;
658
673
  }
659
674
 
660
- export { type AdaptedComponentProps, type Block, type BlockAdapterOptions, type ButtonGroupFormSetup, DynamicFormField, type DynamicFormFieldProps, type FileUploadProgress, FormEngine, type FormEngineLayoutSettings, type FormEngineProps, type FormEngineStyleRules, type FormEngineSubmitButtonSetup, type FormErrors, FormFieldConfig, FormLayoutSettings, type PageSpeedFormConfig, type PageSpeedFormMethod, type PageSpeedFormSubmissionConfig, PageSpeedFormSubmissionError, type PageSpeedFormSubmissionFormat, type PageSpeedFormSubmissionResult, type RailsApiConfig, type RailsErrorResponse, type SerializedFormData, type UseContactFormOptions, type UseContactFormReturn, type UseFileUploadOptions, type UseFileUploadReturn, createBlockAdapter, createBlockAdapters, deserializeErrors, isValidEmail, serializeForRails, standardInputTransformer, submitPageSpeedForm, useContactForm, useFileUpload };
675
+ export { type AdaptedComponentProps, type Block, type BlockAdapterOptions, type ButtonGroupFormSetup, DynamicFormField, type DynamicFormFieldProps, type FileUploadProgress, FormEngine, type FormEngineLayoutSettings, type FormEngineProps, type FormEngineSetup, type FormEngineStyleRules, type FormEngineSubmitButtonSetup, type FormErrors, FormFieldConfig, FormLayoutSettings, type PageSpeedFormConfig, type PageSpeedFormMethod, type PageSpeedFormSubmissionConfig, PageSpeedFormSubmissionError, type PageSpeedFormSubmissionFormat, type PageSpeedFormSubmissionResult, type RailsApiConfig, type RailsErrorResponse, type SerializedFormData, type UseContactFormOptions, type UseContactFormReturn, type UseFileUploadOptions, type UseFileUploadReturn, createBlockAdapter, createBlockAdapters, deserializeErrors, isValidEmail, serializeForRails, standardInputTransformer, submitPageSpeedForm, useContactForm, useFileUpload };
@@ -795,22 +795,40 @@ var DEFAULT_SUBMIT_LABEL = "Submit";
795
795
  var DEFAULT_BUTTON_GROUP_LABEL = "Subscribe";
796
796
  var DEFAULT_BUTTON_VARIANT = "default";
797
797
  var DEFAULT_BUTTON_GROUP_SIZE = "default";
798
- function FormEngine({
799
- api,
800
- fields,
801
- formLayoutSettings,
802
- successMessage,
803
- onSubmit,
804
- onSuccess,
805
- onError,
806
- navigate,
807
- resetOnSuccess,
808
- uploadTokens: externalUploadTokens,
809
- onFileUpload: externalOnFileUpload,
810
- onFileRemove: externalOnFileRemove,
811
- isUploading: externalIsUploading,
812
- uploadProgress: externalUploadProgress
813
- }) {
798
+ function FormEngine(props) {
799
+ const {
800
+ formEngineSetup,
801
+ defaultFields,
802
+ defaultStyleRules,
803
+ api: directApi,
804
+ fields: directFields,
805
+ formLayoutSettings: directFormLayoutSettings,
806
+ successMessage: directSuccessMessage,
807
+ onSubmit: directOnSubmit,
808
+ onSuccess: directOnSuccess,
809
+ onError: directOnError,
810
+ navigate: directNavigate,
811
+ resetOnSuccess: directResetOnSuccess,
812
+ uploadTokens: directUploadTokens,
813
+ onFileUpload: directOnFileUpload,
814
+ onFileRemove: directOnFileRemove,
815
+ isUploading: directIsUploading,
816
+ uploadProgress: directUploadProgress
817
+ } = props;
818
+ const api = directApi ?? formEngineSetup?.api;
819
+ const fields = directFields ?? formEngineSetup?.fields;
820
+ const formLayoutSettings = directFormLayoutSettings ?? formEngineSetup?.formLayoutSettings;
821
+ const successMessage = directSuccessMessage ?? formEngineSetup?.successMessage;
822
+ const onSubmit = directOnSubmit ?? formEngineSetup?.onSubmit;
823
+ const onSuccess = directOnSuccess ?? formEngineSetup?.onSuccess;
824
+ const onError = directOnError ?? formEngineSetup?.onError;
825
+ const navigate = directNavigate ?? formEngineSetup?.navigate;
826
+ const resetOnSuccess = directResetOnSuccess ?? formEngineSetup?.resetOnSuccess;
827
+ const externalUploadTokens = directUploadTokens ?? formEngineSetup?.uploadTokens;
828
+ const externalOnFileUpload = directOnFileUpload ?? formEngineSetup?.onFileUpload;
829
+ const externalOnFileRemove = directOnFileRemove ?? formEngineSetup?.onFileRemove;
830
+ const externalIsUploading = directIsUploading ?? formEngineSetup?.isUploading;
831
+ const externalUploadProgress = directUploadProgress ?? formEngineSetup?.uploadProgress;
814
832
  const {
815
833
  styleRules: userStyleRules,
816
834
  formLayout = "standard",
@@ -818,16 +836,21 @@ function FormEngine({
818
836
  submitButtonSetup
819
837
  } = formLayoutSettings ?? {};
820
838
  const isButtonGroup = formLayout === "button-group";
839
+ const formFields = React2.useMemo(() => {
840
+ if (fields && fields.length > 0) return fields;
841
+ if (defaultFields && defaultFields.length > 0) return defaultFields;
842
+ return [];
843
+ }, [fields, defaultFields]);
821
844
  const styleRules = React2.useMemo(
822
845
  () => ({
823
- formContainer: userStyleRules?.formContainer ?? DEFAULT_STYLE_RULES.formContainer,
824
- fieldsContainer: userStyleRules?.fieldsContainer ?? DEFAULT_STYLE_RULES.fieldsContainer,
825
- fieldClassName: userStyleRules?.fieldClassName ?? DEFAULT_STYLE_RULES.fieldClassName,
826
- formClassName: userStyleRules?.formClassName ?? DEFAULT_STYLE_RULES.formClassName,
827
- successMessageClassName: userStyleRules?.successMessageClassName ?? DEFAULT_STYLE_RULES.successMessageClassName,
828
- errorMessageClassName: userStyleRules?.errorMessageClassName ?? DEFAULT_STYLE_RULES.errorMessageClassName
846
+ formContainer: userStyleRules?.formContainer ?? defaultStyleRules?.formContainer ?? DEFAULT_STYLE_RULES.formContainer,
847
+ fieldsContainer: userStyleRules?.fieldsContainer ?? defaultStyleRules?.fieldsContainer ?? DEFAULT_STYLE_RULES.fieldsContainer,
848
+ fieldClassName: userStyleRules?.fieldClassName ?? defaultStyleRules?.fieldClassName ?? DEFAULT_STYLE_RULES.fieldClassName,
849
+ formClassName: userStyleRules?.formClassName ?? defaultStyleRules?.formClassName ?? DEFAULT_STYLE_RULES.formClassName,
850
+ successMessageClassName: userStyleRules?.successMessageClassName ?? defaultStyleRules?.successMessageClassName ?? DEFAULT_STYLE_RULES.successMessageClassName,
851
+ errorMessageClassName: userStyleRules?.errorMessageClassName ?? defaultStyleRules?.errorMessageClassName ?? DEFAULT_STYLE_RULES.errorMessageClassName
829
852
  }),
830
- [userStyleRules]
853
+ [userStyleRules, defaultStyleRules]
831
854
  );
832
855
  const {
833
856
  uploadTokens: internalUploadTokens,
@@ -843,7 +866,7 @@ function FormEngine({
843
866
  const onFileUpload = externalOnFileUpload ?? internalUploadFiles;
844
867
  const onFileRemove = externalOnFileRemove ?? internalRemoveFile;
845
868
  const { form, submissionError, formMethod, resetSubmissionState } = useContactForm({
846
- formFields: fields,
869
+ formFields,
847
870
  formConfig: api,
848
871
  onSubmit,
849
872
  onSuccess: (data) => {
@@ -878,7 +901,7 @@ function FormEngine({
878
901
  Form,
879
902
  {
880
903
  form,
881
- fields: isButtonGroup ? fields : void 0,
904
+ fields: isButtonGroup ? formFields : void 0,
882
905
  formConfig: legacyFormConfig,
883
906
  method: formMethod,
884
907
  notificationConfig: {
@@ -900,7 +923,7 @@ function FormEngine({
900
923
  styleRules?.fieldsContainer
901
924
  )
902
925
  },
903
- fields.map((field) => /* @__PURE__ */ React2.createElement(
926
+ formFields.map((field) => /* @__PURE__ */ React2.createElement(
904
927
  "div",
905
928
  {
906
929
  key: field.name,