[WEB-5459] feat(codemods): add function declaration transformer with tests (#8137)

- Add jscodeshift-based codemod to convert arrow function components to function declarations
- Support React.FC, observer-wrapped, and forwardRef components
- Include comprehensive test suite covering edge cases
- Add npm script to run transformer across codebase
- Target only .tsx files in source directories, excluding node_modules and declaration files

* [WEB-5459] chore: updates after running codemod

---------

Co-authored-by: sriramveeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
Aaron 2025-11-20 19:09:40 +07:00 committed by GitHub
parent 90866fb925
commit 83fdebf64d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
1771 changed files with 17003 additions and 13856 deletions

View file

@ -2,4 +2,6 @@
import React from "react";
export const WorkspaceAppSwitcher = () => <></>;
export function WorkspaceAppSwitcher() {
return <></>;
}

View file

@ -7,4 +7,6 @@ export type TBillingActionsButtonProps = {
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const BillingActionsButton = observer((props: TBillingActionsButtonProps) => <></>);
export const BillingActionsButton = observer(function BillingActionsButton(props: TBillingActionsButtonProps) {
return <></>;
});

View file

@ -13,7 +13,7 @@ type TPlanFrequencyToggleProps = {
setSelectedFrequency: (frequency: TBillingFrequency) => void;
};
export const PlanFrequencyToggle: FC<TPlanFrequencyToggleProps> = observer((props) => {
export const PlanFrequencyToggle = observer(function PlanFrequencyToggle(props: TPlanFrequencyToggleProps) {
const { subscriptionType, monthlyPrice, yearlyPrice, selectedFrequency, setSelectedFrequency } = props;
// derived values
const yearlyDiscount = calculateYearlyDiscount(monthlyPrice, yearlyPrice);

View file

@ -31,7 +31,7 @@ type TPlanDetailProps = {
const COMMON_BUTTON_STYLE =
"relative inline-flex items-center justify-center w-full px-4 py-1.5 text-xs font-medium rounded-lg focus:outline-none transition-all duration-300 animate-slide-up";
export const PlanDetail: FC<TPlanDetailProps> = observer((props) => {
export const PlanDetail = observer(function PlanDetail(props: TPlanDetailProps) {
const { subscriptionType, planDetail, billingFrequency, setBillingFrequency } = props;
// plane hooks
const { t } = useTranslation();

View file

@ -15,7 +15,7 @@ type TPlansComparisonProps = {
setIsCompareAllFeaturesSectionOpen: React.Dispatch<React.SetStateAction<boolean>>;
};
export const PlansComparison = observer((props: TPlansComparisonProps) => {
export const PlansComparison = observer(function PlansComparison(props: TPlansComparisonProps) {
const {
isCompareAllFeaturesSectionOpen,
getBillingFrequency,

View file

@ -12,7 +12,7 @@ import { SettingsHeading } from "@/components/settings/heading";
// local imports
import { PlansComparison } from "./comparison/root";
export const BillingRoot = observer(() => {
export const BillingRoot = observer(function BillingRoot() {
const [isCompareAllFeaturesSectionOpen, setIsCompareAllFeaturesSectionOpen] = useState(false);
const [productBillingFrequency, setProductBillingFrequency] = useState<TProductBillingFrequency>(
DEFAULT_PRODUCT_BILLING_FREQUENCY

View file

@ -2,8 +2,14 @@
import React from "react";
import { observer } from "mobx-react";
export const WorkspaceContentWrapper = observer(({ children }: { children: React.ReactNode }) => (
<div className="flex relative size-full overflow-hidden bg-custom-background-90 rounded-lg transition-all ease-in-out duration-300">
<div className="size-full p-2 flex-grow transition-all ease-in-out duration-300 overflow-hidden">{children}</div>
</div>
));
export const WorkspaceContentWrapper = observer(function WorkspaceContentWrapper({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="flex relative size-full overflow-hidden bg-custom-background-90 rounded-lg transition-all ease-in-out duration-300">
<div className="size-full p-2 flex-grow transition-all ease-in-out duration-300 overflow-hidden">{children}</div>
</div>
);
});

View file

@ -16,7 +16,7 @@ type Props = {
onClose: () => void;
};
export const DeleteWorkspaceModal: React.FC<Props> = observer((props) => {
export const DeleteWorkspaceModal = observer(function DeleteWorkspaceModal(props: Props) {
const { isOpen, data, onClose } = props;
return (

View file

@ -16,7 +16,7 @@ type TDeleteWorkspace = {
workspace: IWorkspace | null;
};
export const DeleteWorkspaceSection: FC<TDeleteWorkspace> = observer((props) => {
export const DeleteWorkspaceSection = observer(function DeleteWorkspaceSection(props: TDeleteWorkspace) {
const { workspace } = props;
// states
const [isOpen, setIsOpen] = useState(false);

View file

@ -10,7 +10,7 @@ import packageJson from "package.json";
// local components
import { PaidPlanUpgradeModal } from "../license";
export const WorkspaceEditionBadge = observer(() => {
export const WorkspaceEditionBadge = observer(function WorkspaceEditionBadge() {
// states
const [isPaidPlanPurchaseModalOpen, setIsPaidPlanPurchaseModalOpen] = useState(false);
// translation

View file

@ -20,7 +20,9 @@ export type TSendWorkspaceInvitationModalProps = {
onSubmit: (data: IWorkspaceBulkInviteFormData) => Promise<void> | undefined;
};
export const SendWorkspaceInvitationModal: React.FC<TSendWorkspaceInvitationModalProps> = observer((props) => {
export const SendWorkspaceInvitationModal = observer(function SendWorkspaceInvitationModal(
props: TSendWorkspaceInvitationModalProps
) {
const { isOpen, onClose, onSubmit } = props;
// store hooks
const { t } = useTranslation();

View file

@ -6,7 +6,7 @@ import { SidebarSearchButton } from "@/components/sidebar/search-button";
// hooks
import { usePowerK } from "@/hooks/store/use-power-k";
export const AppSearch = observer(() => {
export const AppSearch = observer(function AppSearch() {
// store hooks
const { togglePowerKModal } = usePowerK();
// translation

View file

@ -37,7 +37,7 @@ type TExtendedSidebarItemProps = {
isLastChild: boolean;
};
export const ExtendedSidebarItem: FC<TExtendedSidebarItemProps> = observer((props) => {
export const ExtendedSidebarItem = observer(function ExtendedSidebarItem(props: TExtendedSidebarItemProps) {
const { item, handleOnNavigationItemDrop, disableDrag = false, disableDrop = false, isLastChild } = props;
const { t } = useTranslation();
// states

View file

@ -6,4 +6,6 @@ type Props = {
item: IWorkspaceSidebarNavigationItem;
};
export const SidebarItem: FC<Props> = ({ item }) => <SidebarItemBase item={item} />;
export function SidebarItem({ item }: Props) {
return <SidebarItemBase item={item} />;
}

View file

@ -1 +1,3 @@
export const SidebarTeamsList = () => null;
export function SidebarTeamsList() {
return null;
}

View file

@ -8,7 +8,7 @@ type TUpgradeBadge = {
size?: "sm" | "md";
};
export const UpgradeBadge: FC<TUpgradeBadge> = (props) => {
export function UpgradeBadge(props: TUpgradeBadge) {
const { className, size = "sm" } = props;
const { t } = useTranslation();
@ -27,4 +27,4 @@ export const UpgradeBadge: FC<TUpgradeBadge> = (props) => {
{t("sidebar.pro")}
</div>
);
};
}