Fix tcs type errors
CI Pipeline / test (20) (pull_request) Successful in 3m13s
CI Pipeline / test (18) (pull_request) Successful in 3m57s
CI Pipeline / e2e (firefox) (pull_request) Successful in 5m6s
CI Pipeline / e2e (webkit) (pull_request) Successful in 5m16s
CI Pipeline / e2e (chromium) (pull_request) Successful in 14m47s
CI Pipeline / performance (pull_request) Successful in 4m32s
CI Pipeline / storybook (pull_request) Successful in 1m35s
CI Pipeline / visual-regression (pull_request) Failing after 9m55s
CI Pipeline / lint (pull_request) Failing after 49s
CI Pipeline / build (pull_request) Successful in 1m48s

This commit is contained in:
adilallo
2025-12-11 09:05:18 -07:00
parent 92a3337aeb
commit c7e3048c09
92 changed files with 53556 additions and 915 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ const AskOrganizer = memo<AskOrganizerProps>(
}) => {
// Analytics tracking for contact button clicks
const handleContactClick = (
event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>,
_event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>,
) => {
// Track contact button interaction
if (onContactClick) {
+22 -32
View File
@@ -89,47 +89,37 @@ const Button = memo<ButtonProps>(
: hoverOutlineStyles[size];
const baseStyles = `inline-flex items-center justify-start box-border ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${fontStyles[size]} transition-all duration-500 ease-in-out cursor-pointer ${variantStyles[variant]} ${outlineStyles}`;
let finalVariant = variant;
if (disabled) {
finalVariant = "default";
}
const combinedStyles = `${baseStyles} ${className}`;
const accessibilityProps = {
const sharedA11y = {
...(ariaLabel && { "aria-label": ariaLabel }),
...(disabled && { "aria-disabled": "true" }),
...(target && { target }),
...(rel && { rel }),
...(disabled && { "aria-disabled": true }),
tabIndex: disabled ? -1 : 0,
...props,
};
if (href && !disabled) {
return (
<a
href={href}
className={combinedStyles}
onClick={onClick}
{...accessibilityProps}
>
{children}
</a>
);
const anchorProps: React.AnchorHTMLAttributes<HTMLAnchorElement> = {
href,
className: combinedStyles,
onClick,
...sharedA11y,
...(target && { target }),
...(rel && { rel }),
};
return <a {...anchorProps}>{children}</a>;
}
return (
<button
type={type}
className={combinedStyles}
disabled={disabled}
onClick={onClick}
{...accessibilityProps}
>
{children}
</button>
);
const buttonProps: React.ButtonHTMLAttributes<HTMLButtonElement> = {
type,
className: combinedStyles,
disabled,
onClick,
...sharedA11y,
...props,
};
return <button {...buttonProps}>{children}</button>;
},
);
+2 -8
View File
@@ -43,15 +43,9 @@ const Checkbox = memo<CheckboxProps>(
const isInverse = mode === "inverse";
// Base tokens (rough placeholders leveraging existing CSS variables)
const colorSurface = isInverse
? "var(--color-surface-inverse-primary)"
: "var(--color-surface-default-primary)";
const colorContent = isInverse
? "var(--color-content-inverse-primary)"
: "var(--color-content-default-primary)";
const colorBrand = isInverse
? "var(--color-content-inverse-brand-primary)"
: "var(--color-content-default-brand-primary)";
// Visual container depending on state
const baseBox = `flex items-center justify-center shrink-0 w-[var(--measures-sizing-024)] h-[var(--measures-sizing-024)] rounded-[var(--measures-radius-medium)] transition-all duration-200 ease-in-out`;
@@ -106,8 +100,8 @@ const Checkbox = memo<CheckboxProps>(
const accessibilityProps = {
role: "checkbox" as const,
"aria-checked": checked ? "true" : "false",
...(disabled && { "aria-disabled": "true", tabIndex: -1 }),
"aria-checked": checked,
...(disabled && { "aria-disabled": true, tabIndex: -1 }),
...(!disabled && { tabIndex: 0 }),
...(ariaLabel && { "aria-label": ariaLabel }),
...(label && !ariaLabel && { "aria-labelledby": `${checkboxId}-label` }),
-1
View File
@@ -34,7 +34,6 @@ const ContentLockup = memo<ContentLockupProps>(
subtitle,
description,
ctaText,
ctaHref,
buttonClassName = "",
variant = "hero",
linkText,
+1 -1
View File
@@ -18,7 +18,7 @@ interface ContentThumbnailTemplateProps {
}
const ContentThumbnailTemplate = memo<ContentThumbnailTemplateProps>(
({ post, className = "", variant = "vertical", slugOrder }) => {
({ post, className = "", variant = "vertical" }) => {
// Get article-specific background image from frontmatter
const getBackgroundImage = (
post: BlogPost,
+15 -3
View File
@@ -59,7 +59,19 @@ const Header = memo(() => {
},
};
const renderNavigationItems = (size: string) => {
type NavSize =
| "default"
| "xsmall"
| "xsmallUseCases"
| "home"
| "homeMd"
| "homeUseCases"
| "large"
| "largeUseCases"
| "homeXlarge"
| "xlarge";
const renderNavigationItems = (size: NavSize) => {
return navigationItems.map((item, index) => (
<MenuBarItem
key={index}
@@ -91,7 +103,7 @@ const Header = memo(() => {
);
};
const renderLoginButton = (size: string) => {
const renderLoginButton = (size: NavSize) => {
return (
<MenuBarItem href="#" size={size} ariaLabel="Log in to your account">
Log in
@@ -100,7 +112,7 @@ const Header = memo(() => {
};
const renderCreateRuleButton = (
buttonSize: string,
buttonSize: "xsmall" | "small" | "medium" | "large" | "xlarge",
containerSize: "small" | "medium" | "large" | "xlarge",
avatarSize: "small" | "medium" | "large" | "xlarge",
) => {
+15 -3
View File
@@ -67,7 +67,19 @@ const HomeHeader = memo(() => {
},
];
const renderNavigationItems = (size: string) => {
type NavSize =
| "default"
| "xsmall"
| "xsmallUseCases"
| "home"
| "homeMd"
| "homeUseCases"
| "large"
| "largeUseCases"
| "homeXlarge"
| "xlarge";
const renderNavigationItems = (size: NavSize) => {
return navigationItems.map((item, index) => (
<MenuBarItem
key={index}
@@ -125,7 +137,7 @@ const HomeHeader = memo(() => {
);
};
const renderLoginButton = (size: string) => {
const renderLoginButton = (size: NavSize) => {
return (
<MenuBarItem
href="#"
@@ -139,7 +151,7 @@ const HomeHeader = memo(() => {
};
const renderCreateRuleButton = (
buttonSize: string,
buttonSize: "xsmall" | "small" | "medium" | "large" | "xlarge",
containerSize: "small" | "medium" | "large" | "xlarge",
avatarSize: "small" | "medium" | "large" | "xlarge",
) => {
+1 -1
View File
@@ -160,7 +160,7 @@ const MenuBarItem = memo<MenuBarItemProps>(
const accessibilityProps = {
...(ariaLabel && { "aria-label": ariaLabel }),
...(disabled && { "aria-disabled": "true" }),
...(disabled && { "aria-disabled": true }),
role: "menuitem" as const,
tabIndex: disabled ? -1 : 0,
...props,
+1 -1
View File
@@ -11,7 +11,7 @@ interface NumberedCardProps {
}
const NumberedCard = memo<NumberedCardProps>(
({ number, text, iconShape, iconColor }) => {
({ number, text, iconShape: _iconShape, iconColor: _iconColor }) => {
return (
<div className="bg-[var(--color-surface-inverse-primary)] rounded-[12px] p-5 shadow-lg flex flex-col gap-4 sm:p-8 sm:gap-8 sm:flex-row sm:items-center lg:p-8 lg:gap-0 lg:flex-row lg:items-stretch lg:relative lg:h-[238px]">
{/* Section Number - Top right (lg breakpoint) */}
+2 -2
View File
@@ -141,7 +141,7 @@ const QuoteBlock = memo<QuoteBlockProps>(
type: "missing_props",
message: "QuoteBlock requires quote and author props",
quote: !!quote,
author: !!author,
author,
});
}
return null; // Don't render if missing required props
@@ -184,7 +184,7 @@ const QuoteBlock = memo<QuoteBlockProps>(
<div className="relative">
{!imageError ? (
<Image
src={avatarSrc}
src={currentAvatarSrc}
alt={`Portrait of ${author}`}
width={64}
height={64}
+3 -9
View File
@@ -33,15 +33,9 @@ const RadioButton = ({
const isInverse = mode === "inverse";
// Base tokens (using same design tokens as Checkbox)
const colorSurface = isInverse
? "var(--color-surface-inverse-primary)"
: "var(--color-surface-default-primary)";
const colorContent = isInverse
? "var(--color-content-inverse-primary)"
: "var(--color-content-default-primary)";
const colorBrand = isInverse
? "var(--color-content-inverse-brand-primary)"
: "var(--color-content-default-brand-primary)";
// Visual container depending on state
const baseBox = `flex items-center justify-center shrink-0 w-[var(--measures-sizing-024)] h-[var(--measures-sizing-024)] rounded-[var(--measures-radius-medium)] transition-all duration-200 ease-in-out`;
@@ -89,7 +83,7 @@ const RadioButton = ({
const radioId = id || `radio-${generatedId}`;
const handleToggle = useCallback(
(e: React.MouseEvent | React.KeyboardEvent) => {
(_e: React.MouseEvent | React.KeyboardEvent) => {
if (!disabled && onChange && !checked) {
onChange({ checked: true, value });
}
@@ -118,8 +112,8 @@ const RadioButton = ({
}}
tabIndex={0}
role="radio"
aria-checked={checked ? "true" : "false"}
{...(disabled && { "aria-disabled": "true" })}
aria-checked={checked}
{...(disabled && { "aria-disabled": true })}
{...(ariaLabel && { "aria-label": ariaLabel })}
{...(label && !ariaLabel && { "aria-labelledby": `${radioId}-label` })}
id={radioId}
+3 -1
View File
@@ -52,7 +52,9 @@ const RelatedArticles = memo<RelatedArticlesProps>(
transform: isMobile
? `translateX(calc(50% - 130px - ${currentIndex * 260}px))`
: "none",
scrollBehavior: !isMobile ? "smooth" : "auto",
scrollBehavior: (!isMobile
? "smooth"
: "auto") as React.CSSProperties["scrollBehavior"],
}),
[isMobile, currentIndex],
);
+20 -5
View File
@@ -8,6 +8,7 @@ import React, {
useEffect,
useCallback,
memo,
useImperativeHandle,
} from "react";
import SelectDropdown from "./SelectDropdown";
import SelectOption from "./SelectOption";
@@ -61,6 +62,11 @@ const Select = forwardRef<HTMLButtonElement, SelectProps>(
const selectRef = useRef<HTMLButtonElement>(null);
const menuRef = useRef<HTMLDivElement>(null);
useImperativeHandle(
ref,
() => selectRef.current as HTMLButtonElement | null,
);
// Handle click outside to close menu
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
@@ -260,11 +266,20 @@ const Select = forwardRef<HTMLButtonElement, SelectProps>(
// Handle children (option elements)
const selectedOption = React.Children.toArray(children).find(
(child) =>
React.isValidElement(child) && child.props.value === selectedValue,
) as
| React.ReactElement<{ value: string; children: React.ReactNode }>
| undefined;
(
child,
): child is React.ReactElement<{
value: string;
children: React.ReactNode;
}> => {
if (!React.isValidElement(child)) return false;
const props = child.props as {
value?: string;
children?: React.ReactNode;
};
return props.value === selectedValue;
},
);
return selectedOption
? String(selectedOption.props.children)
: placeholder;
+53 -54
View File
@@ -60,64 +60,63 @@ const WebVitalsDashboard = memo(() => {
// Set up Web Vitals tracking
if (typeof window !== "undefined") {
import("web-vitals").then(
({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
// Track Largest Contentful Paint
getLCP((metric) => {
setVitals((prev) => ({
...prev,
lcp: {
value: Math.round(metric.value),
rating: metric.rating,
},
}));
});
import("web-vitals").then((webVitals) => {
const { getCLS, getFID, getFCP, getLCP, getTTFB } = webVitals as any;
// Track Largest Contentful Paint
getLCP((metric) => {
setVitals((prev) => ({
...prev,
lcp: {
value: Math.round(metric.value),
rating: metric.rating,
},
}));
});
// Track First Input Delay
getFID((metric) => {
setVitals((prev) => ({
...prev,
fid: {
value: Math.round(metric.value),
rating: metric.rating,
},
}));
});
// Track First Input Delay
getFID((metric) => {
setVitals((prev) => ({
...prev,
fid: {
value: Math.round(metric.value),
rating: metric.rating,
},
}));
});
// Track Cumulative Layout Shift
getCLS((metric) => {
setVitals((prev) => ({
...prev,
cls: {
value: Math.round(metric.value * 1000) / 1000,
rating: metric.rating,
},
}));
});
// Track Cumulative Layout Shift
getCLS((metric) => {
setVitals((prev) => ({
...prev,
cls: {
value: Math.round(metric.value * 1000) / 1000,
rating: metric.rating,
},
}));
});
// Track First Contentful Paint
getFCP((metric) => {
setVitals((prev) => ({
...prev,
fcp: {
value: Math.round(metric.value),
rating: metric.rating,
},
}));
});
// Track First Contentful Paint
getFCP((metric) => {
setVitals((prev) => ({
...prev,
fcp: {
value: Math.round(metric.value),
rating: metric.rating,
},
}));
});
// Track Time to First Byte
getTTFB((metric) => {
setVitals((prev) => ({
...prev,
ttfb: {
value: Math.round(metric.value),
rating: metric.rating,
},
}));
});
},
);
// Track Time to First Byte
getTTFB((metric) => {
setVitals((prev) => ({
...prev,
ttfb: {
value: Math.round(metric.value),
rating: metric.rating,
},
}));
});
});
}
}, []);