Implement use cases page

This commit is contained in:
adilallo
2026-05-17 21:41:54 -06:00
parent b6b9b63608
commit 450da4d8ab
78 changed files with 1870 additions and 118 deletions
+8 -2
View File
@@ -1,16 +1,20 @@
"use client";
import { memo } from "react";
import { memo, useId } from "react";
import { IconView } from "./Icon.view";
import type { IconProps } from "./Icon.types";
const IconContainer = memo<IconProps>(
({ icon, title, description, className = "", onClick }) => {
({ icon, title, description, className = "", onClick, interactive: interactiveProp = true }) => {
const layoutTitleId = useId();
const handleClick = () => {
if (!interactiveProp) return;
if (onClick) onClick();
};
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (!interactiveProp) return;
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
handleClick();
@@ -23,6 +27,8 @@ const IconContainer = memo<IconProps>(
title={title}
description={description}
className={className}
interactive={interactiveProp}
layoutTitleId={layoutTitleId}
onClick={handleClick}
onKeyDown={handleKeyDown}
/>
+8
View File
@@ -4,6 +4,11 @@ export interface IconProps {
description: string;
className?: string;
onClick?: () => void;
/**
* When false, renders a static tile (no button semantics or focus ring).
* @default true
*/
interactive?: boolean;
}
export interface IconViewProps {
@@ -11,6 +16,9 @@ export interface IconViewProps {
title: string;
description: string;
className: string;
interactive: boolean;
/** Stable id for `aria-labelledby` when `interactive` is false. */
layoutTitleId: string;
onClick: () => void;
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;
}
+22 -11
View File
@@ -7,30 +7,41 @@ export function IconView({
title,
description,
className,
interactive,
layoutTitleId,
onClick,
onKeyDown,
}: IconViewProps) {
const interactionClass = interactive
? "cursor-pointer transition-all duration-200 hover:scale-[1.02] hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-brand-primary)] focus:ring-offset-2"
: "cursor-default";
return (
<div
className={`border border-[var(--color-border-default-primary)] flex flex-col h-[350px] items-start justify-between p-[var(--measures-spacing-020)] relative w-[288px] bg-transparent cursor-pointer transition-all duration-200 hover:scale-[1.02] hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-brand-primary)] focus:ring-offset-2 ${className}`}
tabIndex={0}
role="button"
aria-label={`${title}: ${description}`}
onClick={onClick}
onKeyDown={onKeyDown}
data-figma-node="22084-859659"
className={`relative flex h-[350px] w-full min-w-[240px] max-w-[480px] flex-col items-start justify-between border border-solid border-[var(--color-border-default-secondary)] bg-transparent p-[var(--measures-spacing-020)] ${interactionClass} ${className}`}
tabIndex={interactive ? 0 : undefined}
role={interactive ? "button" : "article"}
aria-label={interactive ? `${title}: ${description}` : undefined}
aria-labelledby={interactive ? undefined : layoutTitleId}
onClick={interactive ? onClick : undefined}
onKeyDown={interactive ? onKeyDown : undefined}
>
{/* Icon */}
<div className="shrink-0 w-[36px] h-[36px] flex items-center justify-center">
<div className="flex h-9 w-9 shrink-0 items-center justify-center">
{icon}
</div>
{/* Title - Centered with auto space above and below */}
<h3 className="font-inter font-normal text-[32px] leading-[36px] text-[var(--color-content-default-primary)] w-full">
{/* Title — Figma XX Large / Label (32 / 36) */}
<h3
id={interactive ? undefined : layoutTitleId}
className="w-full text-left font-inter text-[32px] font-normal leading-[36px] text-[var(--color-content-default-primary)]"
>
{title}
</h3>
{/* Description */}
<p className="font-inter font-medium text-[10px] leading-[14px] uppercase text-[var(--color-content-default-primary)] w-full">
{/* Body: X Small / Paragraph (12/16) per Figma; 14/20 on md<lg only (Section 22084-859062) */}
<p className="w-full text-left font-inter font-normal text-[length:var(--text-x-small-paragraph)] leading-[length:var(--text-x-small-paragraph--line-height)] text-[var(--color-content-default-primary)] md:text-[length:var(--text-small-paragraph)] md:leading-[length:var(--text-small-paragraph--line-height)] lg:text-[length:var(--text-x-small-paragraph)] lg:leading-[length:var(--text-x-small-paragraph--line-height)]">
{description}
</p>
</div>