[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

@ -19,7 +19,7 @@ type TBreadcrumbBlockProps = {
};
// TODO: remove this component and use web Link component
const BreadcrumbBlock: React.FC<TBreadcrumbBlockProps> = (props) => {
function BreadcrumbBlock(props: TBreadcrumbBlockProps) {
const { label, icon, disableTooltip = false } = props;
return (
@ -30,7 +30,7 @@ const BreadcrumbBlock: React.FC<TBreadcrumbBlockProps> = (props) => {
</Breadcrumbs.ItemWrapper>
</>
);
};
}
export default meta;
type Story = StoryObj<typeof Breadcrumbs>;

View file

@ -10,16 +10,18 @@ type BreadcrumbsProps = {
isLoading?: boolean;
};
export const BreadcrumbItemLoader = () => (
<div className="flex items-center gap-2 h-7 animate-pulse">
<div className="group h-full flex items-center gap-2 rounded px-2 py-1 text-sm font-medium">
<span className="h-full w-5 bg-custom-background-80 rounded" />
<span className="h-full w-16 bg-custom-background-80 rounded" />
export function BreadcrumbItemLoader() {
return (
<div className="flex items-center gap-2 h-7 animate-pulse">
<div className="group h-full flex items-center gap-2 rounded px-2 py-1 text-sm font-medium">
<span className="h-full w-5 bg-custom-background-80 rounded" />
<span className="h-full w-16 bg-custom-background-80 rounded" />
</div>
</div>
</div>
);
);
}
const Breadcrumbs = ({ className, children, onBack, isLoading = false }: BreadcrumbsProps) => {
function Breadcrumbs({ className, children, onBack, isLoading = false }: BreadcrumbsProps) {
const [isSmallScreen, setIsSmallScreen] = React.useState(false);
React.useEffect(() => {
@ -82,7 +84,7 @@ const Breadcrumbs = ({ className, children, onBack, isLoading = false }: Breadcr
{isSmallScreen && childrenArray.length === 1 && childrenArray}
</div>
);
};
}
// breadcrumb item
type BreadcrumbItemProps = {
@ -91,7 +93,7 @@ type BreadcrumbItemProps = {
isLast?: boolean;
};
const BreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) => {
function BreadcrumbItem(props: BreadcrumbItemProps) {
const { component, showSeparator = true, isLast = false } = props;
return (
<div className="flex items-center gap-0.5 h-6">
@ -99,7 +101,7 @@ const BreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) => {
{showSeparator && !isLast && <BreadcrumbSeparator />}
</div>
);
};
}
// breadcrumb icon
type BreadcrumbIconProps = {
@ -107,10 +109,10 @@ type BreadcrumbIconProps = {
className?: string;
};
const BreadcrumbIcon: React.FC<BreadcrumbIconProps> = (props) => {
function BreadcrumbIcon(props: BreadcrumbIconProps) {
const { children, className } = props;
return <div className={cn("flex size-4 items-center justify-start overflow-hidden", className)}>{children}</div>;
};
}
// breadcrumb label
type BreadcrumbLabelProps = {
@ -118,14 +120,14 @@ type BreadcrumbLabelProps = {
className?: string;
};
const BreadcrumbLabel: React.FC<BreadcrumbLabelProps> = (props) => {
function BreadcrumbLabel(props: BreadcrumbLabelProps) {
const { children, className } = props;
return (
<div className={cn("relative line-clamp-1 block max-w-[150px] overflow-hidden truncate", className)}>
{children}
</div>
);
};
}
// breadcrumb separator
type BreadcrumbSeparatorProps = {
@ -135,7 +137,7 @@ type BreadcrumbSeparatorProps = {
showDivider?: boolean;
};
const BreadcrumbSeparator: React.FC<BreadcrumbSeparatorProps> = (props) => {
function BreadcrumbSeparator(props: BreadcrumbSeparatorProps) {
const { className, containerClassName, iconClassName, showDivider = false } = props;
return (
<div className={cn("relative flex items-center justify-center h-full px-1.5 py-1", className)}>
@ -150,7 +152,7 @@ const BreadcrumbSeparator: React.FC<BreadcrumbSeparatorProps> = (props) => {
</div>
</div>
);
};
}
// breadcrumb wrapper
type BreadcrumbItemWrapperProps = {
@ -162,7 +164,7 @@ type BreadcrumbItemWrapperProps = {
isLast?: boolean;
};
const BreadcrumbItemWrapper: React.FC<BreadcrumbItemWrapperProps> = (props) => {
function BreadcrumbItemWrapper(props: BreadcrumbItemWrapperProps) {
const { label, disableTooltip = false, children, className, type = "link", isLast = false } = props;
return (
<Tooltip tooltipContent={label} position="bottom" disabled={!label || label === "" || disableTooltip}>
@ -179,7 +181,7 @@ const BreadcrumbItemWrapper: React.FC<BreadcrumbItemWrapperProps> = (props) => {
</div>
</Tooltip>
);
};
}
Breadcrumbs.Item = BreadcrumbItem;
Breadcrumbs.Icon = BreadcrumbIcon;

View file

@ -17,7 +17,7 @@ type TBreadcrumbNavigationDropdownProps = {
isLast?: boolean;
};
export const BreadcrumbNavigationDropdown = (props: TBreadcrumbNavigationDropdownProps) => {
export function BreadcrumbNavigationDropdown(props: TBreadcrumbNavigationDropdownProps) {
const { selectedItemKey, navigationItems, navigationDisabled = false, handleOnClick, isLast = false } = props;
const [isOpen, setIsOpen] = React.useState(false);
// derived values
@ -29,31 +29,33 @@ export const BreadcrumbNavigationDropdown = (props: TBreadcrumbNavigationDropdow
// if no selected item, return null
if (!selectedItem) return null;
const NavigationButton = () => (
<Tooltip tooltipContent={selectedItem.title} position="bottom" disabled={isOpen}>
<button
onClick={(e) => {
if (!isLast) {
e.preventDefault();
e.stopPropagation();
handleOnClick?.();
}
}}
className={cn(
"group h-full flex items-center gap-2 px-1.5 py-1 text-sm font-medium text-custom-text-300 cursor-pointer rounded rounded-r-none",
{
"hover:bg-custom-background-80 hover:text-custom-text-100": !isLast,
}
)}
>
<div className="flex @4xl:hidden text-custom-text-300">...</div>
<div className="hidden @4xl:flex gap-2">
{selectedItemIcon && <Breadcrumbs.Icon>{selectedItemIcon}</Breadcrumbs.Icon>}
<Breadcrumbs.Label>{selectedItem.title}</Breadcrumbs.Label>
</div>
</button>
</Tooltip>
);
function NavigationButton() {
return (
<Tooltip tooltipContent={selectedItem.title} position="bottom" disabled={isOpen}>
<button
onClick={(e) => {
if (!isLast) {
e.preventDefault();
e.stopPropagation();
handleOnClick?.();
}
}}
className={cn(
"group h-full flex items-center gap-2 px-1.5 py-1 text-sm font-medium text-custom-text-300 cursor-pointer rounded rounded-r-none",
{
"hover:bg-custom-background-80 hover:text-custom-text-100": !isLast,
}
)}
>
<div className="flex @4xl:hidden text-custom-text-300">...</div>
<div className="hidden @4xl:flex gap-2">
{selectedItemIcon && <Breadcrumbs.Icon>{selectedItemIcon}</Breadcrumbs.Icon>}
<Breadcrumbs.Label>{selectedItem.title}</Breadcrumbs.Label>
</div>
</button>
</Tooltip>
);
}
if (navigationDisabled) {
return <NavigationButton />;
@ -133,4 +135,4 @@ export const BreadcrumbNavigationDropdown = (props: TBreadcrumbNavigationDropdow
})}
</CustomMenu>
);
};
}

View file

@ -19,7 +19,7 @@ type TBreadcrumbNavigationSearchDropdownProps = {
shouldTruncate?: boolean;
};
export const BreadcrumbNavigationSearchDropdown: React.FC<TBreadcrumbNavigationSearchDropdownProps> = (props) => {
export function BreadcrumbNavigationSearchDropdown(props: TBreadcrumbNavigationSearchDropdownProps) {
const {
icon,
title,
@ -102,4 +102,4 @@ export const BreadcrumbNavigationSearchDropdown: React.FC<TBreadcrumbNavigationS
)}
/>
);
};
}