Category Text B
Category selector. It can be placed inside a product item as a category, size or variant selector.
Preview
Code
import classNames from "classnames"; import React, { useState } from "react"; import styles from "./category-text-b.module.css"; type CategoryType = { slug: string; title: React.ReactNode; imageSrc?: string; }; type Props = { className?: string; categories?: CategoryType[]; initialCategorySlug?: string; size?: "small" | "medium" | "large"; rounded?: "none" | "small" | "medium" | "large" | "full"; // Put additional variants here, then define them in the CSS variant?: "default" | "red"; // Behavior when category is selected onSelectCategory?: (categorySlug: string) => void; }; export default function CategoryTextB({ className, categories, initialCategorySlug, size = "medium", rounded = "full", variant, onSelectCategory, }: Props) { // Active slug state const [activeSlug, setActiveSlug] = useState<string>( initialCategorySlug || (categories ? categories[0]?.slug : "") ); return ( <> {categories && ( <div className={[ styles["wrapper"], styles[`s-${size}`], styles[`r-${rounded}`], styles[`variant-${variant}`], className, ].join(" ")} > {categories.map((category) => { return ( <div key={category.slug}> <button type="button" className={[ styles["category-item"], activeSlug === category.slug && styles["active"], ].join(" ")} onClick={() => { setActiveSlug(category.slug); onSelectCategory && onSelectCategory(category.slug); }} > {/* If you use Next.js, replace 'img' with 'Image' element */} {category.imageSrc && ( <img className={styles["item-img"]} src={category.imageSrc} alt={`${category.title}`} width={48} height={48} decoding="async" loading="lazy" /> )} <span className={styles["item-text"]}>{category.title}</span> </button> </div> ); })} </div> )} </> ); }
Design
Figma design file:
Documentation
Properties
Props of the component:
-
className
(string): Specifies the CSS class of the component. -
categories
(Array of CategoryType): Specifies the categories to select. -
initialCategorySlug
(string): Specifies the default selected item slug. -
size
("small" | "medium" | "large"): Specifies the size of the component. -
rounded
("none" | "small" | "medium" | "large" | "full"): Specifies the border radius of each item frame. -
variant
("default" | "red" or a customized value): Specifies the color or theme variant of the component. See the "Sample CSS customization" below for an example of usage. -
onSelectCategory
(function): Fires when an item is clicked.
CategoryType item arguments
slug
(string): Specifies the reference slug text.title
(string or ReactNode): Specifies the item title text.imageSrc
(string): Specifies the URL of the image.
Sample CSS customization
.variant-red { --active-bg-color: #f01a50; --bg-color: transparent; } .variant-red .category-item { box-shadow: 0px 0px 0px 1px rgba(29, 29, 29, 0.31); } .variant-red .category-item.active, .variant-red .category-item:active, .variant-red .category-item:hover { box-shadow: 0px 0px 0px 1px var(--active-bg-color); }