Assess, plan, evolve.
Reusable compiler-aware skills that help coding agents understand, plan, and safely evolve your codebase.
5 packages
This hook is now called useNavigation to avoid confusion with the recent React hook by the same name. It also no longer has the type field and flattens the submission object into the navigation object itself. ### Before ```ts import { useTransition } from '@remix-run/react'; function SomeComponent() { const transition = useTransition(); transition.submission.formData; transition.submission.formMethod; transition.submission.formAction; transition.type; } ``` ### After ```ts import { useNavigation } from '@remix-run/react'; function SomeComponent() { const navigation = useNavigation(); // transition.submission keys are flattened onto `navigation[key]` navigation.formData; navigation.formMethod; navigation.formAction; // this key is removed navigation.type; } ```
## Codemod Description This codemod is designed to replace specific patterns in TypeScript files with updated code logic. It transforms instances of `goto($A)` into `window.location.href = $A;` when the `$A` value is a URL starting with `http://` or `https://`. This refactor makes external navigation more explicit by using `window.location.href`. --- ## Features - **Pattern Matching**: Identifies instances of `goto($A)` in TypeScript files. - **Conditional Replacement**: Applies transformations only when the matched node contains URLs starting with `http://` or `https://`. - **Automated Code Refactoring**: Updates all matching files automatically. - **Logging**: Displays original and transformed code snippets for review. --- ## Workflow Details The codemod works by finding and replacing `goto($A)` with `window.location.href = $A;` based on the condition that `$A` is an external URL starting with `http://` or `https://`. ### Code Transformations: - **Pattern**: `goto($A)` - **Regex Filters**: - `http://` - `https://` - **Replacement**: - `window.location.href = $A;` --- ## Before and After Examples ### Example 1: Internal Navigation (Unchanged) #### Before ```typescript import { goto } from '$app/navigation'; function navigateInternal() { goto('/dashboard', { state: { userId: 42, from: 'home' } }); goto('/dashboard'); } ``` #### After ```typescript import { goto } from '$app/navigation'; function navigateInternal() { goto('/dashboard', { state: { userId: 42, from: 'home' } }); goto('/dashboard'); } ``` - **Explanation**: Internal URLs (like `/dashboard`) remain unchanged, as they do not match the transformation condition. --- ### Example 2: External Navigation with `http://` #### Before ```typescript function navigateExternal() { goto('http://example.com'); } ``` #### After ```typescript function navigateExternal() { window.location.href = 'http://example.com'; } ``` - **Explanation**: External URLs starting with `http://` are transformed into `window.location.href = $A;`. --- ### Example 3: External Navigation with `https://` #### Before ```typescript function navigateExternal() { goto('https://example.com'); } ``` #### After ```typescript function navigateExternal() { window.location.href = 'https://example.com'; } ``` - **Explanation**: External URLs starting with `https://` are also transformed in the same way. --- ## How It Works 1. The script scans all TypeScript files (`*.ts`) in your project. 2. It searches for instances of `goto($A)` and checks if `$A` matches either `http://` or `https://`. 3. When a match is found, the `goto($A)` pattern is replaced with `window.location.href = $A;`. 4. Internal navigation paths are left unchanged, as they do not match the regex condition. --- ## Conclusion This codemod provides an efficient way to refactor external navigation in your TypeScript code by converting `goto($A)` into `window.location.href = $A;` for URLs starting with `http://` or `https://`. It helps make external link handling more explicit and consistent across your project. --- ## License This codemod is open-source and licensed under the MIT License. ```
When using `NavigationMenuLink` together with `NuxtLink` according to the documentation the menu does not dismiss when clicking on a link. ## Example ### Before ```ts < script lang = "ts" > import type { PrimitiveProps } from '@/Primitive' import { useForwardExpose } from '@/shared' export type NavigationMenuLinkEmits = { /** * Event handler called when the user selects a link (via mouse or keyboard). * * Calling `event.preventDefault` in this handler will prevent the navigation menu from closing when selecting that link. */ select: [payload: MouseEvent] } export interface NavigationMenuLinkProps extends PrimitiveProps { /** Used to identify the link as the currently active page. */ active ? : boolean } < /script> < script setup lang = "ts" > import { nextTick } from 'vue' import { Primitive } from '@/Primitive' import { EVENT_ROOT_CONTENT_DISMISS } from './utils' // const LINK_SELECT = "navigationMenu.linkSelect"; const props = withDefaults(defineProps < NavigationMenuLinkProps > (), { as: 'a', }) const emits = defineEmits < NavigationMenuLinkEmits > () useForwardExpose() async function handleClick(ev: MouseEvent) { emits('select', linkSelectEvent) await nextTick() if (!ev.defaultPrevented && !ev.metaKey) { const rootContentDismissEvent = new CustomEvent( EVENT_ROOT_CONTENT_DISMISS, { bubbles: true, cancelable: true, }, ) ev.target?.dispatchEvent(rootContentDismissEvent) } } < /script> < template > < Primitive: as = "as": data - active = "active ? '' : undefined": aria - current = "active ? 'page' : undefined": as - child = "props.asChild" data - radix - vue - collection - item @click = "handleClick" > < slot / > < /Primitive> < /template> ``` ### After ```ts < script lang = "ts" > import type { PrimitiveProps } from '@/Primitive' import { useForwardExpose } from '@/shared' export type NavigationMenuLinkEmits = { /** * Event handler called when the user selects a link (via mouse or keyboard). * * Calling `event.preventDefault` in this handler will prevent the navigation menu from closing when selecting that link. */ select: [payload: CustomEvent < { originalEvent: Event } > ] } export interface NavigationMenuLinkProps extends PrimitiveProps { /** Used to identify the link as the currently active page. */ active ? : boolean } < /script> < script setup lang = "ts" > import { Primitive } from '@/Primitive' import { EVENT_ROOT_CONTENT_DISMISS, LINK_SELECT } from './utils' const props = withDefaults(defineProps < NavigationMenuLinkProps > (), { as: 'a', }) const emits = defineEmits < NavigationMenuLinkEmits > () useForwardExpose() async function handleClick(ev: MouseEvent) { const linkSelectEvent = new CustomEvent(LINK_SELECT, { bubbles: true, cancelable: true, detail: { originalEvent: ev, }, }) emits('select', linkSelectEvent) if (!linkSelectEvent.defaultPrevented && !ev.metaKey) { const rootContentDismissEvent = new CustomEvent( EVENT_ROOT_CONTENT_DISMISS, { bubbles: true, cancelable: true, }, ) ev.target?.dispatchEvent(rootContentDismissEvent) } } < /script> < template > < Primitive: as = "as": data - active = "active ? '' : undefined": aria - current = "active ? 'page' : undefined": as - child = "props.asChild" data - radix - vue - collection - item @click = "handleClick" > < slot / > < /Primitive> < /template> ```
This codemod migrates `useHistory` to `useNavigate` in React Router codebases. It replaces `useHistory` imports and updates all instances of `history.push`, `history.replace`, `go`, `goBack`, and `goForward` to align with the `useNavigate` API. ### Before ```tsx import { useHistory } from "react-router-dom"; const history = useHistory(); history.push("/home"); history.replace("/login"); history.goBack(); ``` ### After ```tsx import { useNavigate } from "react-router-dom"; const navigate = useNavigate(); navigate("/home"); navigate("/login", { replace: true }); navigate(-1); // Equivalent to goBack ``` This codemod simplifies the migration from `useHistory` to `useNavigate`, aligning your code with React Router's latest navigation hooks while preserving functionality.
Migrate Cypress end-to-end tests to Playwright. Transforms test structure, selectors, actions, assertions, and navigation commands.
Build your own codemod!
Describe the migration you need and Wish will create a codemod for you.
Ready to evolve your codebase?
Build tailored, compiler-aware skills to assess, plan, and automate complex codebase changes.