'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "default", {
    enumerable: true,
    get: function() {
        return Form;
    }
});
const _jsxruntime = require("react/jsx-runtime");
const _react = require("react");
const _addbasepath = require("../add-base-path");
const _usemergedref = require("../use-merged-ref");
const _approutercontextsharedruntime = require("../../shared/lib/app-router-context.shared-runtime");
const _formshared = require("../form-shared");
const _links = require("../components/links");
const _types = require("../components/segment-cache/types");
function Form({ replace, scroll, prefetch: prefetchProp, ref: externalRef, ...props }) {
    const router = (0, _react.useContext)(_approutercontextsharedruntime.AppRouterContext);
    const actionProp = props.action;
    const isNavigatingForm = typeof actionProp === 'string';
    // Validate `action`
    if (process.env.NODE_ENV === 'development') {
        if (isNavigatingForm) {
            (0, _formshared.checkFormActionUrl)(actionProp, 'action');
        }
    }
    // Validate `prefetch`
    if (process.env.NODE_ENV === 'development') {
        if (!(prefetchProp === undefined || prefetchProp === false || prefetchProp === null)) {
            console.error('The `prefetch` prop of <Form> must be `false` or `null`');
        }
        if (prefetchProp !== undefined && !isNavigatingForm) {
            console.error('Passing `prefetch` to a <Form> whose `action` is a function has no effect.');
        }
    }
    // TODO(runtime-ppr): allow runtime prefetches in Form
    const prefetch = prefetchProp === false || prefetchProp === null ? prefetchProp : null;
    // Validate `scroll` and `replace`
    if (process.env.NODE_ENV === 'development') {
        if (!isNavigatingForm && (replace !== undefined || scroll !== undefined)) {
            console.error('Passing `replace` or `scroll` to a <Form> whose `action` is a function has no effect.\n' + 'See the relevant docs to learn how to control this behavior for navigations triggered from actions:\n' + '  `redirect()`       - https://nextjs.org/docs/app/api-reference/functions/redirect#parameters\n' + '  `router.replace()` - https://nextjs.org/docs/app/api-reference/functions/use-router#userouter\n');
        }
    }
    // Clean up any unsupported form props (and warn if present)
    for (const key of _formshared.DISALLOWED_FORM_PROPS){
        if (key in props) {
            if (process.env.NODE_ENV === 'development') {
                console.error(`<Form> does not support changing \`${key}\`. ` + (isNavigatingForm ? `If you'd like to use it to perform a mutation, consider making \`action\` a function instead.\n` + `Learn more: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations` : ''));
            }
            delete props[key];
        }
    }
    const isPrefetchEnabled = // if we don't have an action path, we can't prefetch anything.
    !!router && isNavigatingForm && prefetch === null;
    const observeFormVisibilityOnMount = (0, _react.useCallback)((element)=>{
        if (isPrefetchEnabled && router !== null) {
            (0, _links.mountFormInstance)(element, actionProp, router, // We default to PPR. We'll discover whether or not the route supports it with the initial prefetch.
            _types.FetchStrategy.PPR);
        }
        return ()=>{
            (0, _links.unmountPrefetchableInstance)(element);
        };
    }, [
        isPrefetchEnabled,
        actionProp,
        router
    ]);
    const mergedRef = (0, _usemergedref.useMergedRef)(observeFormVisibilityOnMount, externalRef ?? null);
    if (!isNavigatingForm) {
        return /*#__PURE__*/ (0, _jsxruntime.jsx)("form", {
            ...props,
            ref: mergedRef
        });
    }
    const actionHref = (0, _addbasepath.addBasePath)(actionProp);
    return /*#__PURE__*/ (0, _jsxruntime.jsx)("form", {
        ...props,
        ref: mergedRef,
        action: actionHref,
        onSubmit: (event)=>onFormSubmit(event, {
                router,
                actionHref,
                replace,
                scroll,
                onSubmit: props.onSubmit
            })
    });
}
function onFormSubmit(event, { actionHref, onSubmit, replace, scroll, router }) {
    if (typeof onSubmit === 'function') {
        onSubmit(event);
        // if the user called event.preventDefault(), do nothing.
        // (this matches what Link does for `onClick`)
        if (event.defaultPrevented) {
            return;
        }
    }
    if (!router) {
        // Form was somehow used outside of the router (but not in pages, the implementation is forked!).
        // We can't perform a soft navigation, so let the native submit handling do its thing.
        return;
    }
    const formElement = event.currentTarget;
    const submitter = event.nativeEvent.submitter;
    let action = actionHref;
    if (submitter) {
        if (process.env.NODE_ENV === 'development') {
            // the way server actions are encoded (e.g. `formMethod="post")
            // causes some unnecessary dev-mode warnings from `hasUnsupportedSubmitterAttributes`.
            // we'd bail out anyway, but we just do it silently.
            if (hasReactServerActionAttributes(submitter)) {
                return;
            }
        }
        if ((0, _formshared.hasUnsupportedSubmitterAttributes)(submitter)) {
            return;
        }
        // client actions have `formAction="javascript:..."`. We obviously can't prefetch/navigate to that.
        if ((0, _formshared.hasReactClientActionAttributes)(submitter)) {
            return;
        }
        // If the submitter specified an alternate formAction,
        // use that URL instead -- this is what a native form would do.
        // NOTE: `submitter.formAction` is unreliable, because it will give us `location.href` if it *wasn't* set
        // NOTE: this should not have `basePath` added, because we can't add it before hydration
        const submitterFormAction = submitter.getAttribute('formAction');
        if (submitterFormAction !== null) {
            if (process.env.NODE_ENV === 'development') {
                (0, _formshared.checkFormActionUrl)(submitterFormAction, 'formAction');
            }
            action = submitterFormAction;
        }
    }
    const targetUrl = (0, _formshared.createFormSubmitDestinationUrl)(action, formElement);
    // Finally, no more reasons for bailing out.
    event.preventDefault();
    const method = replace ? 'replace' : 'push';
    const targetHref = targetUrl.href;
    router[method](targetHref, {
        scroll
    });
}
function hasReactServerActionAttributes(submitter) {
    // https://github.com/facebook/react/blob/942eb80381b96f8410eab1bef1c539bed1ab0eb1/packages/react-client/src/ReactFlightReplyClient.js#L931-L934
    const name = submitter.getAttribute('name');
    return name && (name.startsWith('$ACTION_ID_') || name.startsWith('$ACTION_REF_'));
}

if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
  Object.defineProperty(exports.default, '__esModule', { value: true });
  Object.assign(exports.default, exports);
  module.exports = exports.default;
}

//# sourceMappingURL=form.js.map