diff --git a/.github/workflows/deduplicate-lock-file.yml b/.github/workflows/deduplicate-lock-file.yml index a50d429581..468a82f1fc 100644 --- a/.github/workflows/deduplicate-lock-file.yml +++ b/.github/workflows/deduplicate-lock-file.yml @@ -23,7 +23,7 @@ jobs: token: ${{ secrets.FORMAT_PAT }} - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 57da20019f..824633f6e0 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -31,7 +31,7 @@ jobs: ref: ${{ github.event.inputs.branch }} - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index e52f37203f..1a47e0cc2d 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -22,7 +22,7 @@ jobs: token: ${{ secrets.FORMAT_PAT }} - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 diff --git a/.github/workflows/pr-actions.yml b/.github/workflows/pr-actions.yml index 9e47361b15..c88a3d7967 100644 --- a/.github/workflows/pr-actions.yml +++ b/.github/workflows/pr-actions.yml @@ -28,7 +28,7 @@ jobs: uses: actions/checkout@v7 - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 744fed1870..9454108868 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -62,7 +62,7 @@ jobs: - name: Setup pnpm if: steps.changed-files.outputs.mode == 'run' - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node if: steps.changed-files.outputs.mode == 'run' diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 1f69a45502..24f26ecf21 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -56,7 +56,7 @@ jobs: ref: ${{ inputs.baseBranch }} - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Install Node.js uses: actions/setup-node@v6 diff --git a/.github/workflows/release-comments-manual.yml b/.github/workflows/release-comments-manual.yml index a9412bce39..62d8db5228 100644 --- a/.github/workflows/release-comments-manual.yml +++ b/.github/workflows/release-comments-manual.yml @@ -25,7 +25,7 @@ jobs: fetch-depth: 0 - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f543de2c7..fa731c548a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -87,7 +87,7 @@ jobs: token: ${{ secrets.FORMAT_PAT }} - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Install Node.js uses: actions/setup-node@v6 @@ -116,7 +116,7 @@ jobs: uses: actions/checkout@v7 - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 @@ -151,7 +151,7 @@ jobs: fetch-depth: 0 - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 @@ -184,7 +184,7 @@ jobs: fetch-depth: 0 - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 diff --git a/.github/workflows/test-integration-run.yml b/.github/workflows/test-integration-run.yml index 91fab70456..68dc80fcff 100644 --- a/.github/workflows/test-integration-run.yml +++ b/.github/workflows/test-integration-run.yml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@v7 - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node ${{ inputs.node_version }} uses: actions/setup-node@v6 diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 0e5a82e96d..5773e25b87 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -63,9 +63,6 @@ jobs: if [ "${{ github.event_name }}" = "push" ]; then echo "Selected integration suite: full (push to main)" echo "type=full" >> "$GITHUB_OUTPUT" - elif [ "${{ github.event.pull_request.head.ref }}" = "v8" ]; then - echo "Selected integration suite: dev (v8 PR)" - echo "type=dev" >> "$GITHUB_OUTPUT" elif [ "${{ github.event.pull_request.draft }}" = "true" ]; then echo "Selected integration suite: base (draft PR)" echo "type=base" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index 6c8b8e7ebd..71c6a2b557 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -37,7 +37,7 @@ jobs: uses: actions/checkout@v7 - name: Setup pnpm - uses: pnpm/action-setup@v6.0.9 + uses: pnpm/action-setup@v6.0.10 - name: Setup node uses: actions/setup-node@v6 diff --git a/contributors.yml b/contributors.yml index 759fd10a60..a399fdfb45 100644 --- a/contributors.yml +++ b/contributors.yml @@ -256,6 +256,7 @@ - kklem0 - kno-raziel - knownasilya +- kobihikri - koojaa - KostiantynPopovych - KubasuIvanSakwa @@ -446,6 +447,7 @@ - sunnyraindy - sushichan044 - swalker326 +- syedsohailhussain1 - szhsin - tanayv - thecode00 diff --git a/packages/react-router/.changes/patch.submit-relative-option.md b/packages/react-router/.changes/patch.submit-relative-option.md new file mode 100644 index 0000000000..5daed14b08 --- /dev/null +++ b/packages/react-router/.changes/patch.submit-relative-option.md @@ -0,0 +1 @@ +Properly respect the `relative` option in `useSubmit`/`fetcher.submit` when resolivng the `action` path diff --git a/packages/react-router/__tests__/dom/data-browser-router-test.tsx b/packages/react-router/__tests__/dom/data-browser-router-test.tsx index f8c33542c2..00124d62ee 100644 --- a/packages/react-router/__tests__/dom/data-browser-router-test.tsx +++ b/packages/react-router/__tests__/dom/data-browser-router-test.tsx @@ -4132,6 +4132,100 @@ function testDomRouter( }); }); + describe('submit() with relative="path"', () => { + it("submits relative to the URL for navigations", async () => { + let router = createTestRouter( + [ + { + path: "inbox", + action: () => "INDEX", + children: [ + { + path: "messages", + action: () => "MESSAGES", + Component() { + let actionData = useActionData(); + return

{actionData}

; + }, + }, + { + path: "messages/:id", + Component() { + let submit = useSubmit(); + return ( + + ); + }, + }, + ], + }, + ], + { window: getWindow("/inbox/messages/1") }, + ); + render(); + + fireEvent.click(screen.getByText("Submit")); + await waitFor(() => screen.getByText("MESSAGES")); + expect(router.state.location.pathname).toBe("/inbox/messages"); + }); + + it("submits relative to the URL for fetchers", async () => { + let router = createTestRouter( + [ + { + path: "inbox", + action: () => "INDEX", + children: [ + { + path: "messages", + action: () => "MESSAGES", + }, + { + path: "messages/:id", + Component() { + let fetcher = useFetcher(); + return ( + <> + + {fetcher.data ?

{fetcher.data}

: null} + + ); + }, + }, + ], + }, + ], + { window: getWindow("/inbox/messages/1") }, + ); + render(); + + fireEvent.click(screen.getByText("Submit")); + await waitFor(() => screen.getByText("MESSAGES")); + }); + }); + describe("useSubmit/Form FormData", () => { it("gathers form data on
submissions", async () => { let actionSpy = jest.fn(); diff --git a/packages/react-router/lib/dom/lib.tsx b/packages/react-router/lib/dom/lib.tsx index 94ad1aae67..f779abea62 100644 --- a/packages/react-router/lib/dom/lib.tsx +++ b/packages/react-router/lib/dom/lib.tsx @@ -2603,6 +2603,7 @@ export function useSubmit(): SubmitFunction { await routerFetch(key, currentRouteId, options.action || action, { defaultShouldRevalidate: options.defaultShouldRevalidate, preventScrollReset: options.preventScrollReset, + relative: options.relative, formData, body, formMethod: options.method || (method as HTMLFormMethod), @@ -2613,6 +2614,7 @@ export function useSubmit(): SubmitFunction { await routerNavigate(options.action || action, { defaultShouldRevalidate: options.defaultShouldRevalidate, preventScrollReset: options.preventScrollReset, + relative: options.relative, formData, body, formMethod: options.method || (method as HTMLFormMethod), diff --git a/packages/react-router/lib/router/router.ts b/packages/react-router/lib/router/router.ts index 97d346fa04..db266eab0e 100644 --- a/packages/react-router/lib/router/router.ts +++ b/packages/react-router/lib/router/router.ts @@ -7680,11 +7680,11 @@ function persistAppliedTransitions( } function createDeferred() { - let resolve: (val?: any) => Promise; - let reject: (error?: Error) => Promise; + let resolve!: (val?: T) => Promise; + let reject!: (error?: Error) => Promise; let promise = new Promise((res, rej) => { - resolve = async (val: T) => { - res(val); + resolve = async (val?: T) => { + res(val as T); try { await promise; } catch {} @@ -7698,9 +7698,7 @@ function createDeferred() { }); return { promise, - //@ts-ignore resolve, - //@ts-ignore reject, }; }