Implementation of icon card
This commit is contained in:
@@ -9,6 +9,8 @@ import Progress from "../components/Progress";
|
||||
import Create from "../components/Create";
|
||||
import Input from "../components/Input";
|
||||
import InputWithCounter from "../components/InputWithCounter";
|
||||
import IconCard from "../components/IconCard";
|
||||
import { getAssetPath } from "../../lib/assetUtils";
|
||||
|
||||
export default function ComponentsPreview() {
|
||||
const [alertVisible, setAlertVisible] = useState({
|
||||
@@ -413,6 +415,32 @@ export default function ComponentsPreview() {
|
||||
</div>
|
||||
</Create>
|
||||
</section>
|
||||
|
||||
{/* IconCard Component Section */}
|
||||
<section className="space-y-[var(--spacing-scale-024)]">
|
||||
<h2 className="font-bricolage-grotesque text-[32px] leading-[40px] font-bold text-[var(--color-content-default-primary)]">
|
||||
IconCard Component
|
||||
</h2>
|
||||
|
||||
<div className="bg-[var(--color-surface-default-secondary)] rounded-[var(--radius-300,12px)] p-[var(--spacing-scale-032)] space-y-[var(--spacing-scale-024)]">
|
||||
<div className="flex flex-wrap gap-[var(--spacing-scale-024)]">
|
||||
<IconCard
|
||||
icon={
|
||||
<img
|
||||
src={getAssetPath("assets/Vector_WorkerCoop.svg")}
|
||||
alt=""
|
||||
className="w-[36px] h-[36px]"
|
||||
width="36"
|
||||
height="36"
|
||||
/>
|
||||
}
|
||||
title="Worker's cooperatives"
|
||||
description="Employee-owned businesses often need to clarify how power is shared, decisions are made, and how processes operate within their organizations."
|
||||
onClick={() => console.log("IconCard clicked")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import { IconCardView } from "./IconCard.view";
|
||||
import type { IconCardProps } from "./IconCard.types";
|
||||
|
||||
const IconCardContainer = memo<IconCardProps>(
|
||||
({ icon, title, description, className = "", onClick }) => {
|
||||
const handleClick = () => {
|
||||
if (onClick) onClick();
|
||||
};
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
if (event.key === "Enter" || event.key === " ") {
|
||||
event.preventDefault();
|
||||
handleClick();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<IconCardView
|
||||
icon={icon}
|
||||
title={title}
|
||||
description={description}
|
||||
className={className}
|
||||
onClick={handleClick}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
IconCardContainer.displayName = "IconCard";
|
||||
|
||||
export default IconCardContainer;
|
||||
@@ -0,0 +1,16 @@
|
||||
export interface IconCardProps {
|
||||
icon: React.ReactNode;
|
||||
title: string;
|
||||
description: string;
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
export interface IconCardViewProps {
|
||||
icon: React.ReactNode;
|
||||
title: string;
|
||||
description: string;
|
||||
className: string;
|
||||
onClick: () => void;
|
||||
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
"use client";
|
||||
|
||||
import type { IconCardViewProps } from "./IconCard.types";
|
||||
|
||||
export function IconCardView({
|
||||
icon,
|
||||
title,
|
||||
description,
|
||||
className,
|
||||
onClick,
|
||||
onKeyDown,
|
||||
}: IconCardViewProps) {
|
||||
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}
|
||||
>
|
||||
{/* Icon */}
|
||||
<div className="shrink-0 w-[36px] h-[36px] flex 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}
|
||||
</h3>
|
||||
|
||||
{/* Description */}
|
||||
<p className="font-inter font-medium text-[10px] leading-[14px] uppercase text-[var(--color-content-default-primary)] w-full">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default } from "./IconCard.container";
|
||||
export type { IconCardProps } from "./IconCard.types";
|
||||
Reference in New Issue
Block a user