Shared React Component Library
Relevant source files
The following files were used as context for generating this wiki page:The CyberPath project utilizes a shared library of React components to build a consistent and interactive user interface. This library, located in src/components/react/, provides a set of reusable, styleable, and accessible UI primitives. The components are built using React, Headless UI for accessibility and state management, and styled with Tailwind CSS, managed via the clsx utility. Key dependencies include @headlessui/react, clsx, and framer-motion for animations.
These components form the building blocks for more complex features, such as the ReactiveDatatable, which composes Table and Pagination components to display certification data. The library is designed to be flexible, with components like Button and NavbarItem capable of rendering as either buttons or links based on their props.
Core Components
The library consists of several key components that can be composed to create complex UI structures.
| Component | Description | Source File |
|---|---|---|
Button | A highly versatile button that can also render as a link. Supports multiple styles and color variants. | src/components/react/button.tsx |
Link | A wrapper for the <a> tag, integrated with Headless UI for data interactivity. | src/components/react/link.tsx |
Navbar | A set of composite components for building navigation bars. | src/components/react/navbar.tsx |
Pagination | A set of composite components for creating pagination controls. | src/components/react/pagination.tsx |
Table | A set of composite components for displaying tabular data with features like striping and clickable rows. | src/components/react/table.tsx |
Styling and Architecture
The components use a consistent styling architecture defined in src/components/react/button.tsx. A styles object contains Tailwind CSS classes organized by base styles, variants (solid, outline, plain), and an extensive list of color themes. The clsx utility is used to conditionally apply these classes based on component props. This approach centralizes styling logic and promotes reusability.
Sources: src/components/react/button.tsx:5-200, package.json:13-28
Button Component
The Button is a foundational component that can render as either a standard <button> element or an anchor <a> tag, depending on whether an href prop is provided. It leverages Headless UI's Button for accessibility when used as a button, and a custom Link component when used as a link.
Sources: src/components/react/button.tsx:216-237
Props and Variants
The Button component's appearance is controlled by a set of mutually exclusive props: color, outline, and plain.
// src/components/react/button.tsx:202-214
type ButtonProps = (
| {
color?: keyof typeof styles.colors;
outline?: never;
plain?: never;
}
| {
color?: never;
outline: true;
plain?: never;
}
| {
color?: never;
outline?: never;
plain: true;
}
) & {
className?: string;
children: React.ReactNode;
} & (Omit<Headless.ButtonProps, "as" | "className"> | Omit<React.ComponentPropsWithoutRef<typeof Link>, "className">);
color: Applies a solid background color style. If not specified, it defaults todark/zinc.outline: Renders a button with a transparent background and a border.plain: Renders a button with a transparent background and no border.
The following diagram illustrates the rendering logic based on the href prop.
This diagram shows how the Button component decides whether to render a link or a button.
Sources: src/components/react/button.tsx:223-236
Color Options
The color prop for the solid variant accepts numerous predefined values, each corresponding to a set of Tailwind CSS classes for background, border, text, and icon colors.
| Color Value | Description |
|---|---|
dark/zinc | Default. Dark zinc background. |
light | Light background, dark text. |
dark/white | Dark background, switches to white in dark mode. |
dark | Dark zinc background. |
white | White background, dark text. |
zinc | Medium zinc background. |
indigo, cyan, red, orange, amber, yellow, lime, green, emerald, teal, sky, blue, violet, purple, fuchsia, pink, rose | Various color themes. |
Sources: src/components/react/button.tsx:75-198
TouchTarget
The Button component wraps its children in a TouchTarget helper component. This utility increases the clickable area to a minimum of 44x44px on touch devices for improved accessibility, without visually altering the button's size.
Sources: src/components/react/button.tsx:242-253
Link Component
The Link component is a simple wrapper around an HTML <a> tag. It is integrated with @headlessui/react's DataInteractive to ensure proper accessibility states. It is intended to be a placeholder that can be replaced by a framework-specific link component (like Next.js's <Link>) for client-side routing.
Sources: src/components/react/link.tsx:11-23
Navbar Component
The Navbar is a composite component used for building application navigation. It is composed of several smaller parts that provide structure and functionality.
Navbar: The main container<nav>element.NavbarSection: Adivthat groups items, usingframer-motion'sLayoutGroupfor animations between items.NavbarItem: The core interactive element, which can be a button or a link. It displays an animated underline for thecurrentitem.NavbarDivider: A visual separator.NavbarSpacer: An element to push content to the sides.NavbarLabel: A<span>for text content within aNavbarItem.
The following diagram shows a typical structure of a Navbar.
This diagram illustrates how Navbar sub-components are assembled to create a navigation bar.
Sources: src/components/react/navbar.tsx
The NavbarItem uses framer-motion to animate an indicator for the currently active link, providing a smooth visual transition.
// src/components/react/navbar.tsx:81-86
<span className={clsx(className, "relative")}>
{current && (
<motion.span
layoutId="current-indicator"
className="absolute inset-x-2 -bottom-2.5 h-0.5 rounded-full bg-zinc-950 dark:bg-white"
/>
)}
{/* ... Link or Button rendering ... */}
</span>
Table Component
The Table is another composite component designed for displaying tabular data. It uses React Context to pass properties down to child components, enabling features like striped rows and clickable rows.
Architecture and Context
Two context providers, TableContext and TableRowContext, manage the table's state and behavior.
TableContext: Providesbleed,dense,grid, andstripedboolean props to all child components.TableRowContext: Provideshref,target, andtitleprops to cells within a specific row, allowing the entire row to function as a link.
This diagram shows the flow of props via React Context within the Table components.
Sources: src/components/react/table.tsx:8-40, 71-97
Component Parts
| Component | Description |
|---|---|
Table | The main wrapper that sets up TableContext. |
TableHead | The <thead> element. |
TableBody | The <tbody> element. |
TableRow | The <tr> element. Sets up TableRowContext if href is provided. |
TableHeader | The <th> element. |
TableCell | The <td> element. Consumes context to render a row-spanning link if href is available. |
Sources: src/components/react/table.tsx
Pagination Component
The Pagination component provides a complete set of controls for navigating paginated data. It is composed of several parts that are used together.
Pagination: The main<nav>container.PaginationPrevious/PaginationNext: Buttons for moving to the previous or next page. They use theButtoncomponent and are disabled if theirhrefprop isnull.PaginationList: A container for the page numbers, typically hidden on small screens.PaginationPage: AButtonrepresenting a specific page number. It has acurrentstate.PaginationGap: A separator (...) for when there are too many pages to display.
Sources: src/components/react/pagination.tsx
Usage in ReactiveDatatable
The ReactiveDatatable component is a prime example of how this component library is used to build a complex, interactive UI. It combines the Table and Pagination components to display a searchable and paginated list of certifications.
This diagram shows the composition of Table and Pagination within ReactiveDatatable.
Sources: src/components/astro/database/reactive-datatable.tsx:14-25, 256-353
Conclusion
The Shared React Component Library in CyberPath provides a robust and flexible foundation for the application's user interface. By leveraging React, Headless UI, and a centralized Tailwind CSS strategy, it delivers accessible, consistent, and composable components. The thoughtful architecture, seen in the use of React Context in the Table and conditional rendering in the Button, allows for the creation of complex and interactive UIs like the ReactiveDatatable with clean and maintainable code.