Skip to main content
Version: 1.0.0

Components & Design System

Author: Carmine Antonio Bonavoglia Creation Date: 29/10/2025
Last Reviewer: Carmine Antonio Bonavoglia Last Updated: 31/10/2025

Overview

Components.js is a component showcase and design system reference page serving as the central hub for:

  • Component discovery: Browse all reusable UI components with live examples
  • Design tokens: Visualize colors, typography, box styles, button variations
  • Theme integration: Real-time display of colors from Redux-based theme store
  • Development reference: Examples for developers to copy patterns and component configurations

The page operates as an interactive component library organized into three tabs:

  1. Global Components (ComponentsManager) — 20+ components including Cards, Buttons, DatePickers, Filters, Headers, Modals, Charts
  2. Dynamic Tables (DynamicTables) — Data visualization with LinearChartBox, TableBox, DoubleChartsBox
  3. Color System (ColorSystem) — Comprehensive theme color palette from Redux with 60+ color tokens

File location: /src/pages/Components.js

Key responsibilities:

  • Display tabbed interface for component discovery and testing
  • Showcase ComponentsManager with full component inventory
  • Render responsive card-based grid layouts with clamp() sizing
  • Integrate Redux theme store for dynamic color display
  • Provide state management for date pickers and filters within showcase
  • Serve as single source of truth for design system reference

Architecture & Component Hierarchy

Components (page - main entry point)

├─ Ant Design Tabs (3 tabs)

├─ Tab 1: "Global Components"
│ └─ ComponentsManager (comprehensive component showcase)
│ ├─ HeaderComponent showcase
│ ├─ ButtonsComponent (all button types)
│ ├─ CustomCard showcase (2 variations)
│ ├─ ModalSection (modal examples)
│ ├─ MessageSection (message/notification examples)
│ ├─ DatePickerComponent showcase
│ │ ├─ SingleDatePickerComponent
│ │ └─ RangePickerComponent
│ ├─ FilterComponent
│ ├─ CatalogueCard showcase (4 variations)
│ ├─ AssetMonitorItem showcase (5 variations with badges)
│ ├─ SummaryCard + ComparisonCard (KPI section)
│ ├─ SimpleChart (data visualization)
│ └─ LoadingCard showcase (3 variations)

├─ Tab 2: "Dynamic Tables"
│ └─ DynamicTables
│ ├─ LinearChartBox
│ ├─ TableBox
│ └─ DoubleChartsBox

└─ Tab 3: "Color System"
└─ ColorSystem (Redux-connected)
├─ Default Colors display (6 colors)
├─ Status Colors display (4 colors)
├─ Primary Shades display (7 shades 100-700)
├─ Secondary Shades display (7 shades)
├─ Complementary Shades display (7 shades)
├─ Grey Shades display (7 shades)
├─ Background Colors display (4 colors)
├─ Box Styles showcase (5 styles)
├─ Button/Link Styles showcase (10+ button variations)
└─ Typography showcase (H1-H5 + labels)

Components.js (Page Layer)

Structure & Logic

const Components = () => {
const items = [
{
key: "1",
label: "Global Components",
children: <ComponentsManager />,
},
{
key: "2",
label: "Dynamic Tables",
children: <DynamicTables />,
},
{
key: "3",
label: "Color System",
children: <ColorSystem />,
},
];

return (
<Tabs
defaultActiveKey="1" // Opens "Global Components" by default
items={items}
style={{
padding: "clamp(0.5rem, 1.5vw, 1rem)",
fontSize: "clamp(0.875rem, 1.6vw, 1rem)",
}}
/>
);
};

Responsive Design Patterns

The page uses CSS clamp() function extensively for responsive sizing:

/* Pattern: clamp(minSize, preferredSize, maxSize) */

/* Padding: min 0.5rem, preferred 1.5vw, max 1rem */
padding: clamp(0.5rem, 1.5vw, 1rem)

/* Font size: min 0.875rem, preferred 1.6vw, max 1rem */
fontSize: clamp(0.875rem, 1.6vw, 1rem)

Benefits:

  • Fluid scaling between mobile and desktop without media queries
  • Responsive without breakpoints
  • Maintains readability at all viewport sizes
  • Reduces CSS complexity

ComponentsManager (Tab 1 - Global Components)

Overview & Purpose

ComponentsManager is a comprehensive component showcase displaying 20+ reusable UI components across 12 sections. Each component is presented with live examples, state management, and documentation.

State Management

// Date picker states (local component state)
const [selectedDate, setSelectedDate] = useState(null);
const [dateRange, setDateRange] = useState(null);

// Handlers
const handleDateChange = (date) => {
setSelectedDate(date); // Update single date
};

const handleDateRangeChange = (dates) => {
setDateRange(dates); // Update [startDate, endDate]
};

// Display
<Text type="secondary">
Date range:{" "}
{dateRange
? `${dateRange[0].format("DD/MM/YYYY")} - ${dateRange[1].format(
"DD/MM/YYYY"
)}`
: "None"}
</Text>;

Sections & Components (Detailed Breakdown)

1. Header Component

Purpose: Display page headers with title + action button

Example Configuration:

<HeaderComponent
title="Gateways - Analytics"
buttonText="Create your report"
onButtonClick={handleCreateReport}
useSpaceBetween={false}
isVisible={true}
/>

Render location: Wrapped in SimpleCard for visual consistency

Related file: /src/components/Components/Headers/HeaderComponent.js


2. Buttons Component

Purpose: Showcase all button types and states

Section count: 9 subsections

  1. Standard Buttons — Primary, Outline, Secondary, Accent, Disabled
  2. Status Buttons — Success, Info, Warning, Error
  3. Validation Status — Incomplete, Modelist Rev., Spaarkly Rev., Client Rev., In Publication (rectangle + circle variants)
  4. Sizes — Small, Default, Large
  5. Buttons with Icons — 5 icon+text combinations
  6. Icon Only Buttons — 5 icon-only buttons with tooltips
  7. Button Shapes — Default, Circle (icon), Round, Rounded with icon
  8. Full Width Buttons — Block-width variants (3 styles)
  9. Ghost Buttons — On dark background with primary, default, dashed variants
  10. Link Buttons — Link button + Link danger

Component Variations Rendered:

<PrimaryButton>Primary</PrimaryButton>
<OutlineButton>Outline</OutlineButton>
<SecondaryButton>Secondary</SecondaryButton>
<AccentButton>Accent</AccentButton>
<SuccessButton>Success</SuccessButton>
<InfoButton>Information</InfoButton>
<WarningButton>Warning</WarningButton>
<ErrorButton>Error</ErrorButton>
<IconButton icon={<SearchOutlined />} tooltip="Search" />
<LinkButton>Link Button</LinkButton>

Related file: /src/components/Components/MainComponents/ButtonsComponent.js

Related components:

  • /src/components/Components/Buttons/Buttons.js — Button style definitions
  • /src/components/Components/Buttons/ButtonState.js — Validation status badges

3. Custom Card Component

Purpose: Showcase flexible card component with custom headers, icons, and content

Example Configurations:

// Card 1: User Info (with icon + tooltip)
<CustomCard
title="Informazioni Utente"
icon={<InfoCircleOutlined />}
height="clamp(9.375rem, 20vw, 12.5rem)"
tooltipText="Informazioni dettagliate sull'utente"
>
<div style={{...}}>
<Text>Nome: Mario Rossi</Text>
<Text>Email: mario.rossi@example.com</Text>
<Text>Ruolo: Amministratore</Text>
</div>
</CustomCard>

// Card 2: Statistics (with custom header color)
<CustomCard
title="Statistiche Recenti"
headerColor={PRIMARY_300}
textColor={PRIMARY_700}
height="clamp(9.375rem, 20vw, 12.5rem)"
>
<div style={{...}}>
<Text style={{...}}>1,234</Text>
<Text style={{...}}>VISUALIZZAZIONI TOTALI</Text>
</div>
</CustomCard>

Layout Grid:

┌─────────────────────────────┐
│ 2 columns (flex, wrap) │
│ gap: clamp(0.625rem, 2vw, 1.25rem)
│ minWidth: clamp(15.625rem, 30vw, 18.75rem)

│ [Card 1] [Card 2] │
└─────────────────────────────┘

Component Props:

  • title (string) — Card header title
  • icon (React.ReactNode) — Icon to display in header
  • height (string) — Responsive height with clamp()
  • headerColor (hex) — Header background color
  • textColor (hex) — Header text color
  • tooltipText (string) — Tooltip content
  • showTooltip (boolean) — Show/hide tooltip icon

Related file: /src/components/Components/Cards/CustomCard.js


4. Modal Box Section

Purpose: Showcase modal components and workflows

Component: ModalSection

Related file: /src/components/Components/MainComponents/ModalSection.js


5. Messages Section

Purpose: Display notification/message component examples

Component: MessageSection

Related file: /src/components/Components/Modals/MessageSection.js


6. Date Pickers

Purpose: Showcase single date picker and date range picker components

Two-column layout:

┌─────────────────────────────────────┐
│ Left Column │ Right Column │
│ Single Date Picker │ Date Range Pick │
└─────────────────────────────────────┘

Single Date Picker Example:

<SingleDatePickerComponent
value={selectedDate}
onChange={handleDateChange}
/>

// Display selected date
<Text type="secondary">
Selected date: {selectedDate ? selectedDate.format('DD/MM/YYYY') : 'None'}
</Text>

Date Range Picker Example:

<RangePickerComponent
value={dateRange}
onChange={handleDateRangeChange}
/>

// Display selected range
<Text type="secondary">
Date range: {dateRange ?
`${dateRange[0].format('DD/MM/YYYY')} - ${dateRange[1].format('DD/MM/YYYY')}` :
'None'}
</Text>

State Flow:

  • User selects date(s) in picker component
  • onChange handler updates local state
  • Display text updates reactively
  • Both pickers are independent

Related files:

  • /src/components/Components/MainComponents/DatePickerComponent.js
  • /src/components/Components/Pickers/ (if separate picker components exist)

7. Filter Component

Purpose: Showcase filter/search component

Component: FilterComponent

Related file: /src/components/Components/Filters/FilterComponent.js


Purpose: Display featured catalogues with asset counts and badges

Layout Grid:

┌────────────────────────────────────────┐
│ 4 columns (20% width each) │
│ [Card1] [Card2] [Card3] [Card4] │
└────────────────────────────────────────┘

Configurations:

// Card 1: Default
<CatalogueCard />

// Card 2: Custom title + asset count
<CatalogueCard
title="SUMMER TOUR"
assetCount={212}
/>

// Card 3: With badge count
<CatalogueCard
title="SMITH OPTICS"
assetCount={46}
badgeCount={2}
/>

// Card 4: Another example
<CatalogueCard
title="BOSS EYEWEAR"
assetCount={117}
/>

Component Props:

  • title (string) — Catalogue name
  • assetCount (number) — 3D asset count
  • badgeCount (number) — Badge/notification count

Related file: /src/components/Components/Cards/CatalogueCard.js


9. Info Box (Asset Monitor Items)

Purpose: Display asset statistics in a horizontal monitoring bar

Layout Grid:

┌────────────────────────────────────────┐
│ 5 columns (20% width each) │
│ [Stat1] [Stat2] [Stat3] [Stat4] [Stat5]
└────────────────────────────────────────┘

Five Statistics Displayed:

// 1. Total 3D Assets
<AssetMonitorItem
count="2544"
label="TOTAL 3D ASSETS"
isFirst={true}
/>

// 2. Main 3D Assets
<AssetMonitorItem
count="679"
label="MAIN 3D ASSETS"
/>

// 3. Published
<AssetMonitorItem
count="2138"
label="PUBLISHED"
sublabel="3D ASSETS"
/>

// 4. To Be Validated (with badge)
<AssetMonitorItem
count="144"
label="TO BE VALIDATED"
sublabel="3D ASSETS"
badgeCount={2}
/>

// 5. In The Making (with custom color)
<AssetMonitorItem
count="110"
label="IN THE MAKING"
sublabel="3D ASSETS"
color={token.colorPrimary}
isLast={true}
/>

Component Props:

  • count (string) — Number to display
  • label (string) — Primary label
  • sublabel (string) — Secondary label below primary
  • badgeCount (number) — Badge number (optional)
  • color (hex) — Custom color override
  • isFirst (boolean) — Add left border radius
  • isLast (boolean) — Add right border radius

Related file: /src/components/Components/Cards/AssetMonitorItem.js


10. Details Box (KPI Section)

Purpose: Display key performance indicators with trends

Layout Grid:

┌─────────────────────────────────────────┐
│ Left (20%) │ Center (58%) │ Right (20%)
│ Summary │ Chart │ Summary
│ + Compare │ │ + Compare
└─────────────────────────────────────────┘

Left Column (Users KPI):

<SummaryCard
title="Number of users (last 7 days)"
value="3307"
subtitle="TOTAL USER"
/>
<ComparisonCard
title="Gap between previous week"
value="1003"
subtitle="TOTAL USER"
isPositive={true}
/>

Center Column (Chart):

<SimpleChart /> // Data visualization

Right Column (Sessions KPI):

<SummaryCard
title="Number of sessions (last 7 days)"
value="6143"
subtitle="TOTAL SESSIONS"
/>
<ComparisonCard
title="Gap between previous week"
value="-13%"
subtitle="TOTAL SESSIONS"
isPositive={false}
/>

Component Props:

SummaryCard:

  • title (string) — KPI title
  • value (string) — Main metric value
  • subtitle (string) — Metric label

ComparisonCard:

  • title (string) — Comparison title
  • value (string|number) — Value or percentage
  • subtitle (string) — Label
  • isPositive (boolean) — Green (true) or red (false) indicator

Related files:

  • /src/components/Components/Cards/SummaryCard.js
  • /src/components/Components/Cards/ComparisonCard.js
  • /src/components/Components/Charts/SimpleChart.js

11. Loading Card Section

Purpose: Showcase loading state component in multiple variations

Layout Grid:

┌────────────────────────────┐
│ 3 columns (30% width each) │
│ [Loading1] [Loading2] [L3] │
└────────────────────────────┘

Variations:

// Variation 1: Default
<LoadingCard />

// Variation 2: Small with custom message
<LoadingCard
size="small"
message="Caricamento dati..."
/>

// Variation 3: Custom height
<LoadingCard
height="200px"
message="Caricamento grafico..."
/>

Component Props:

  • size (string) — 'small', 'default', 'large'
  • message (string) — Loading message text
  • height (string|number) — Custom container height

Related file: /src/components/Components/Cards/LoadingCard.js


Key Styling Patterns in ComponentsManager

Responsive Spacing

// Margin bottom between sections
marginBottom: "clamp(1rem, 2vw, 1.5rem)";

// Gap between grid items
gap: "clamp(0.625rem, 2vw, 1.25rem)";

// Minimum width for grid columns
minWidth: "clamp(15.625rem, 30vw, 18.75rem)";

Section Titles

<Title level={3} style={{
marginBottom: 'clamp(1rem, 2vw, 1.5rem)',
color: PRIMARY_700,
textAlign: 'left'
}}>
{Section Name}
</Title>

Card Wrapping

<SimpleCard>{children}</SimpleCard>

DynamicTables (Tab 2)

Overview

Tab 2 displays data visualization components for complex data rendering:

const DynamicTables = () => {
return (
<div style={{ padding: 'clamp(0.625rem, 2vw, 1.25rem)' }}>
<Title level={3} style={{...}}>Linear Chart Box</Title>
<LinearChartBox />

<Title level={3} style={{...}}>Table Box</Title>
<TableBox />

<Title level={3} style={{...}}>Double Charts Box</Title>
<DoubleChartsBox />
</div>
);
};

Components

1. LinearChartBox

Purpose: Display linear/trend charts for time-series data

Related file: /src/components/Components/Charts/LinearChartBox.js


2. TableBox

Purpose: Display dynamic/sortable data tables

Related file: /src/components/Components/Tables/TableBox.js


3. DoubleChartsBox

Purpose: Display two charts side-by-side for comparison

Related file: /src/components/Components/Charts/DoubleChartBox.js


ColorSystem (Tab 3 - Redux-Connected)

Overview & Redux Integration

The ColorSystem component is Redux-connected and displays the entire theme color palette from the Redux store in real-time.

import { useSelector } from "react-redux";

const ColorSystem = () => {
// Fetch theme from Redux store
const theme = useSelector((state) => state.theme);

// Extract all color categories
const PRIMARY = theme.variant.primary;
const ACCENT = theme.variant.accent;
// ... etc
};

Color Structure from Redux Store

The theme Redux store provides colors organized in 7 categories:

const theme = {
// 1. Variant Colors (6 colors)
variant: {
primary: "#...", // Primary brand color
accent: "#...", // Accent color
black: "#000000", // Black
secondary: "#...", // Secondary
complementary: "#...", // Complementary
white: "#FFFFFF", // White
},

// 2. Status Colors (4 colors)
status: {
success: "#52c41a", // Green
error: "#ff4d4f", // Red
warning: "#faad14", // Orange
info: "#1890ff", // Blue
},

// 3. Primary Shades (7 levels: 100-700)
primary: {
primary100: "#...", // Lightest
primary200: "#...",
primary300: "#...",
primary400: "#...",
primary500: "#...", // Mid-tone
primary600: "#...",
primary700: "#...", // Darkest
},

// 4. Secondary Shades (7 levels)
secondary: {
/* 100-700 */
},

// 5. Complementary Shades (7 levels)
complementary: {
/* 100-700 */
},

// 6. Grey Shades (7 levels)
grey: {
/* 100-700 */
},

// 7. Background Colors (4 colors)
background: {
primaryBg: "#...", // Primary background
whiteBg: "#FFFFFF", // White background
greyBg: "#...", // Grey background
secondaryBg: "#...", // Secondary background
},
};

Color Display Sections (8 sections)

1. Default Colors (6 colors)

Rendered:

  • Primary, Accent, Black, Secondary, Complementary, White

Component:

<ColorBox color="primary" label="Primary" hexCode={PRIMARY} />

2. Status Colors (4 colors)

Rendered:

  • Success (#52c41a), Error (#ff4d4f), Warning (#faad14), Info (#1890ff)

Usage: Alerts, validation states, badges


3. Primary Shades (7 colors: 100-700)

Light to Dark: primary100 → primary700

Usage: Backgrounds, text, hover states


4. Secondary Shades (7 colors: 100-700)

Light to Dark: secondary100 → secondary700

Usage: Borders, accents, secondary components


5. Complementary Shades (7 colors: 100-700)

Light to Dark: complementary100 → complementary700

Usage: Complementary design elements


6. Grey Shades (7 colors: 100-700)

Light to Dark: grey100 → grey700

Usage: Neutral backgrounds, borders, disabled states


7. Background Colors (4 colors)

Rendered:

  • Primary Background, White Background, Grey Background, Secondary Background

Usage: Page backgrounds, card backgrounds


8. Box Styles (5 styles)

From theme.boxStyles:

const boxStyles = {
defaultBox: {...}, // Base box style
borderBox: {...}, // With border
greyBox: {...}, // Grey background
raisedBox: {...}, // Elevated/shadow
floatingBox: {...} // Floating effect
};

Rendered:

<BoxExample
title="Default Box"
style={boxStyles.defaultBox}
/>
<BoxExample
title="Border Box"
style={boxStyles.borderBox}
/>
// ... etc

Two rows of buttons:

Row 1 (Standard):

  • Primary, Outline, Secondary, Accent, Disabled

Row 2 (Status):

  • Success, Information, Warning, Error

Component: Ant Design Button with buttonStyles from theme

<Button type="primary" style={buttonStyles.primary}>Primary</Button>
<Button style={buttonStyles.outline}>Outline</Button>
<Button style={buttonStyles.success}>Success</Button>

10. Typography (6 levels)

Displayed:

  • H1, H2, H3, H4, H5 + Label
  • Font: Inter
  • Shows font size from typography.fontSizes

Styles Shown:

<Title level={1}>Inter - H1 - {typography.fontSizes.h1}</Title>
<Title level={2}>Inter - H2 - {typography.fontSizes.h2}</Title>
// ... H3-H5
<Text type="secondary">Inter - LABEL - {typography.fontSizes.label}</Text>

Typography Features:

  • Underline examples
  • Normal text examples
  • Shows actual pixel sizes from theme

ColorBox Component (Helper)

Used throughout ColorSystem to display individual colors:

const ColorBox = ({ color, label, hexCode }) => (
<div
style={{
marginBottom: "clamp(0.625rem, 2vw, 1.25rem)",
width: "clamp(5rem, 10vw, 7.5rem)",
}}
>
{/* Color swatch */}
<div
style={{
backgroundColor: hexCode,
height: "clamp(1.875rem, 4vw, 2.8125rem)",
width: "100%",
borderRadius: "clamp(0.125rem, 0.5vw, 0.25rem)",
marginBottom: "clamp(0.25rem, 1vw, 0.5rem)",
border:
hexCode === "#FFFFFF"
? "clamp(0.0625rem, 0.2vw, 0.0625rem) solid #E0E0E0"
: "none",
}}
/>

{/* Label + hex code */}
<div style={{ textAlign: "left" }}>
<Text strong style={{ display: "block" }}>
{label}
</Text>
<Text
type="secondary"
style={{ fontSize: "clamp(0.625rem, 1.2vw, 0.75rem)" }}
>
{hexCode}
</Text>
</div>
</div>
);

Props:

  • color (string) — Color identifier (used as key)
  • label (string) — Display name (e.g., "Primary 300")
  • hexCode (string) — Hex color code

Special handling:

  • White colors get a subtle border for visibility
  • Responsive size using clamp()
  • Displays hex code below color label

BoxExample Component (Helper)

Used to showcase box style variations:

const BoxExample = ({ title, style }) => (
<div
style={{
...style,
width: "100%",
height: "clamp(2.5rem, 5vw, 3.75rem)",
borderRadius: "clamp(0.125rem, 0.5vw, 0.25rem)",
padding: "clamp(0.5rem, 1.5vw, 1rem)",
marginBottom: "clamp(0.25rem, 1vw, 0.5rem)",
}}
>
<Text>{title}</Text>
</div>
);

Props:

  • title (string) — Box name/style label
  • style (object) — Style object from theme.boxStyles

Tab State Management & Navigation

Components.js Tab State

const items = [
{ key: "1", label: "Global Components", children: <ComponentsManager /> },
{ key: "2", label: "Dynamic Tables", children: <DynamicTables /> },
{ key: "3", label: "Color System", children: <ColorSystem /> },
];

<Tabs defaultActiveKey="1" items={items} />;

Default Behavior:

  • Tab 1 ("Global Components") opens on page load
  • User can click tabs to switch
  • State managed by Ant Design Tabs component
  • No additional state needed

Tab Content Lazy Loading

Each tab's content (ComponentsManager, DynamicTables, ColorSystem) is rendered conditionally by Ant Design:

  • Only the active tab is rendered in DOM
  • Other tabs' content is mounted/unmounted on tab switch
  • Performance optimization: components not in view don't consume resources

Responsive Design Deep Dive

Clamp() Function Strategy

The entire Components page uses CSS clamp() function for responsive sizing without media queries.

Pattern: clamp(minSize, preferredSize, maxSize)

Examples used throughout:

/* Padding - min 0.5rem, preferred 1.5vw, max 1rem */
padding: clamp(0.5rem, 1.5vw, 1rem)

/* Margin - min 0.625rem, preferred 2vw, max 1.25rem */
margin: clamp(0.625rem, 2vw, 1.25rem)

/* Font size - min 0.875rem, preferred 1.6vw, max 1rem */
fontSize: clamp(0.875rem, 1.6vw, 1rem)

/* Height - min 2.5rem, preferred 5vw, max 3.75rem */
height: clamp(2.5rem, 5vw, 3.75rem)

/* Width - min 15.625rem, preferred 30vw, max 18.75rem */
minWidth: clamp(15.625rem, 30vw, 18.75rem)

/* Border radius - min 0.125rem, preferred 0.5vw, max 0.25rem */
borderRadius: clamp(0.125rem, 0.5vw, 0.25rem)

Breakpoint-Free Responsive Grid

Example: ComponentsManager grid layout

<div
style={{
marginBottom: "clamp(1.25rem, 3vw, 2.5rem)",
display: "flex",
gap: "clamp(0.625rem, 2vw, 1.25rem)",
flexWrap: "wrap",
}}
>
<div style={{ flex: "1", minWidth: "clamp(15.625rem, 30vw, 18.75rem)" }}>
<Card1 />
</div>
<div style={{ flex: "1", minWidth: "clamp(15.625rem, 30vw, 18.75rem)" }}>
<Card2 />
</div>
</div>

Behavior:

  • Mobile: Cards stack (1 per row) due to minWidth constraint
  • Tablet: Cards wrap naturally (2 per row)
  • Desktop: Cards flow across with flex: 1
  • All sizes: Gap and padding scale smoothly

No media queries needed!


Component Composition Patterns

Pattern 1: Wrapped Components in SimpleCard

<Title level={3}>Component Name</Title>
<SimpleCard>
<ActualComponent />
</SimpleCard>

Purpose: Consistent visual container with shadow + border radius

Related component: /src/components/Components/Cards/SimpleCard.js

Pattern 2: Section with Custom Grids

<div
style={{
marginBottom: "clamp(1.25rem, 3vw, 2.5rem)",
display: "flex",
flexWrap: "wrap",
justifyContent: "space-between",
}}
>
<div style={{ width: "20%" }}>
<ComponentVariation1 />
</div>
<div style={{ width: "20%" }}>
<ComponentVariation2 />
</div>
{/* ... more variations */}
</div>

Purpose: Multi-column layout with consistent proportions

Variations:

  • 2 columns: width: 50% with gap
  • 4 columns: width: 22% with gap
  • 5 columns: width: 20% with gap

Pattern 3: Flex with Gap and Wrap

<div
style={{
display: "flex",
gap: "clamp(0.9375rem, 2.5vw, 1.875rem)",
flexWrap: "wrap",
}}
>
<Component1 style={{ flex: "1", minWidth: "..." }} />
<Component2 style={{ flex: "1", minWidth: "..." }} />
</div>

Purpose: Responsive flow layout with auto-wrapping


SimpleCard Component (Key Helper)

Used throughout ComponentsManager for consistent card styling.

Source: /src/components/Components/Cards/SimpleCard.js

function SimpleCard({
children,
title,
onClick,
style,
className,
padding = "1rem",
borderRadius = "clamp(0.25rem, 2vw, 0.5rem)",
}) {
return (
<Card
title={title}
onClick={onClick}
hoverable
styles={{
body: { padding: padding },
}}
style={{
width: "100%",
boxShadow: `clamp(0rem, 0.1vw, 0rem) clamp(0.0625rem, 0.5vw, 0.125rem) clamp(0.25rem, 2vw, 0.5rem) rgba(0, 0, 0, 0.15)`,
cursor: onClick ? "pointer" : "default",
transition: "transform 0.2s",
borderRadius: borderRadius,
...style,
}}
className={className}
>
{children}
</Card>
);
}

Props:

  • children (ReactNode) — Content
  • title (string) — Optional header title
  • onClick (function) — Optional click handler
  • style (object) — Custom styles
  • className (string) — Custom CSS class
  • padding (string) — Custom body padding
  • borderRadius (string) — Custom border radius

Default styling:

  • Hover effect: shadow + transform
  • Box shadow: responsive blur + offset
  • Border radius: clamp() for scaling

CustomCard Component (Complex Helper)

Used for cards with headers, icons, and custom content.

Source: /src/components/Components/Cards/CustomCard.js

const CustomCard = ({
title,
icon,
children,
backgroundColor = "#ffffff",
headerColor = PRIMARY_200,
textColor = PRIMARY_500,
height = "auto",
showTooltip = true,
tooltipText = "Card information",
}) => {
return (
<Card
style={{
borderRadius: "clamp(0.25rem, 2vw, 0.5rem)",
overflow: "hidden",
height: height,
boxShadow: `0 clamp(0.0625rem, 0.5vw, 0.125rem) clamp(0.25rem, 2vw, 0.5rem) rgba(0, 0, 0, 0.08)`,
backgroundColor: backgroundColor,
}}
styles={{
body: {
padding: title ? 0 : "clamp(0.75rem, 4vw, 1.25rem)",
height: "100%",
},
}}
>
{title ? (
<>
{/* Header with icon + tooltip */}
<div
style={{
backgroundColor: headerColor,
padding:
"clamp(0.5rem, 2vw, 0.625rem) clamp(0.75rem, 3vw, 0.9375rem)",
textAlign: "left",
fontWeight: "bold",
fontSize: "clamp(0.75rem, 2vw, 0.875rem)",
color: textColor,
display: "flex",
alignItems: "center",
justifyContent: "space-between",
}}
>
<div style={{ display: "flex", alignItems: "center" }}>
{icon && (
<span
style={{
marginRight:
"clamp(0.25rem, 2vw, 0.5rem)",
}}
>
{icon}
</span>
)}
{title}
</div>
{showTooltip && (
<CustomTooltip title={tooltipText}>
<InfoCircleOutlined
style={{
fontSize:
"clamp(0.75rem, 2vw, 0.875rem)",
color: textColor,
}}
/>
</CustomTooltip>
)}
</div>
{/* Content body */}
<div
style={{
padding: "clamp(0.75rem, 4vw, 1.25rem)",
height: "calc(100% - 2.5rem)",
}}
>
{children}
</div>
</>
) : (
children
)}
</Card>
);
};

Props:

  • title (string) — Header title
  • icon (ReactNode) — Header icon
  • headerColor (hex) — Header background
  • textColor (hex) — Header text color
  • height (string) — Container height
  • showTooltip (boolean) — Show info icon
  • tooltipText (string) — Tooltip content

Key features:

  • Icon + title in header
  • Tooltip info icon (optional)
  • Flexible height
  • Responsive padding with clamp()
  • Full-height content area

Integration Points & Dependencies

Imports (Components.js)

import { Tabs } from "antd";
import ComponentsManager from "../components/Components/ComponentsManager";
import DynamicTables from "../components/Components/DynamicTables";
import ColorSystem from "../components/Components/ColorSystem";

Imports (ComponentsManager.js)

import { useState } from "react";
import { Typography, theme } from "antd";
import { InfoCircleOutlined } from "@ant-design/icons";
import { primaryShades } from "../../theme/theme";

// 20+ component imports
import ButtonsComponent from "./MainComponents/ButtonsComponent";
import HeaderComponent from "./Headers/HeaderComponent";
import CustomCard from "./Cards/CustomCard";
// ... etc (all listed in file)

Imports (ColorSystem.js)

import React from "react";
import { Typography, Button, Divider } from "antd";
import { useSelector } from "react-redux";
import { boxStyles, buttonStyles, typography } from "../../theme/theme";

Redux Store Access

ColorSystem connects to Redux:

const theme = useSelector((state) => state.theme);

Store structure expected:

{
theme: {
variant: { primary, accent, black, secondary, complementary, white },
status: { success, error, warning, info },
primary: { primary100-700 },
secondary: { secondary100-700 },
complementary: { complementary100-700 },
grey: { grey100-700 },
background: { primaryBg, whiteBg, greyBg, secondaryBg }
}
}

Error Handling & Edge Cases

Edge Case 1: Missing Redux Theme

Scenario: Redux theme store is undefined

Current handling: Not explicitly handled in ColorSystem

Recommendation: Add fallback

const theme = useSelector((state) => state.theme) || defaultTheme;

Edge Case 2: Long Component Names

Scenario: Card titles overflow in narrow viewports

Current handling: Text truncates naturally with flex

Recommendation: Add text-overflow styles

{
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}

Edge Case 3: Large Number of Color Boxes

Scenario: 60+ color boxes render in ColorSystem

Performance impact: Moderate (each box is simple div)

Optimization: Not needed for current scale; memoize if >200 items


Performance Considerations

Component Rendering

  1. ComponentsManager: ~20 child components rendered on mount

    • Heavy: ButtonsComponent (10 sections)
    • Heavy: ColorSystem (60+ color boxes)
    • Moderate: DatePickerComponent (2 pickers)
    • Light: All others
  2. Tabs Performance: Ant Design Tabs mounts/unmounts tab content on switch

    • Good for initial load (only active tab rendered)
    • Small delay when switching to inactive tab

Optimization Opportunities

  • Memoize ColorBox component (prevents re-renders)
  • Lazy-load DynamicTables and ColorSystem tab content
  • Virtualize color boxes if count exceeds 100
  • Move ComponentsManager state to custom hook
  • Add React.memo() to ButtonsComponent sections

Memory Usage

  • Components.js: Minimal (just Tabs component)
  • ComponentsManager: High (20+ children)
  • ColorSystem: High (60+ color boxes + Redux subscription)
  • DynamicTables: Depends on data (LinearChartBox, TableBox, DoubleChartsBox)

Testing Strategy

Unit Tests

// Test ColorBox renders correct hex code
test("ColorBox displays correct hex code", () => {
const { getByText } = render(
<ColorBox label="Primary" hexCode="#007AFF" color="primary" />
);
expect(getByText("#007AFF")).toBeInTheDocument();
});

// Test CustomCard shows/hides tooltip
test("CustomCard shows tooltip when showTooltip=true", () => {
const { getByIcon } = render(
<CustomCard title="Test" showTooltip={true}>
Content
</CustomCard>
);
expect(getByIcon(InfoCircleOutlined)).toBeInTheDocument();
});

// Test tab switching
test("Tabs component renders correct active tab", () => {
const { getByText } = render(<Components />);
expect(getByText("Global Components")).toHaveClass("ant-tabs-tab-active");
});

Integration Tests

// Test ComponentsManager renders all sections
test("ComponentsManager renders all 11 sections", () => {
const { getByText } = render(<ComponentsManager />);
expect(getByText("Header")).toBeInTheDocument();
expect(getByText("Buttons")).toBeInTheDocument();
expect(getByText("Custom Card")).toBeInTheDocument();
// ... all 11 sections
});

// Test date picker state updates
test("Date picker updates state correctly", () => {
const { getByDisplayValue } = render(<ComponentsManager />);
const picker = getByTestId("single-date-picker");
userEvent.click(picker);
userEvent.click(getByText("15"));
expect(getByDisplayValue(/15/)).toBeInTheDocument();
});

// Test ColorSystem Redux integration
test("ColorSystem fetches colors from Redux", () => {
const initialState = {
theme: {
variant: { primary: "#007AFF" },
// ... full theme
},
};
const { getByText } = render(
<Provider store={createTestStore(initialState)}>
<ColorSystem />
</Provider>
);
expect(getByText("#007AFF")).toBeInTheDocument();
});

E2E Tests

// Full user journey
test("User navigates all three tabs and sees content", async () => {
// 1. Page loads, Tab 1 active
await expect(page.locator("text=Header")).toBeVisible();

// 2. Click Tab 2
await page.click("text=Dynamic Tables");
await expect(page.locator("text=Linear Chart Box")).toBeVisible();

// 3. Click Tab 3
await page.click("text=Color System");
await expect(page.locator("text=Default Colors")).toBeVisible();

// 4. Verify Redux colors displayed
const primaryColor = await page.locator("text=#007AFF").textContent();
expect(primaryColor).toBeTruthy();
});

State Flow Diagram

┌─────────────────────────────────────────────────────────┐
│ User visits Components page │
└──────────────────┬──────────────────────────────────────┘


┌──────────────────────────┐
│ Components page renders │
│ • Tabs component mounts │
│ • defaultActiveKey="1" │
└──────────────┬───────────┘


┌──────────────────────────────┐
│ Tab 1 Content Renders │
│ ComponentsManager mounts │
│ • 20 components initialize │
│ • DatePicker state created │
│ • All sections render │
└──────────────┬───────────────┘

┌──────────────┴────────────────┬────────────────┐
│ │ │
↓ ↓ ↓
[Tab 2 Click] [Tab 3 Click] [DatePicker Change]
│ │ │
↓ ↓ ↓
DynamicTables ColorSystem mounts handleDateChange()
mounts on demand (Redux connected) → setSelectedDate()
│ │ │
↓ ↓ ↓
Charts render Display 60+ colors Text updates
from data from Redux store reactively

Page layer: /src/pages/Components.js

Tab 1 - ComponentsManager:

  • /src/components/Components/ComponentsManager.js (main)
  • /src/components/Components/MainComponents/ — ButtonsComponent, DatePickerComponent, ModalSection
  • /src/components/Components/Headers/ — HeaderComponent
  • /src/components/Components/Cards/ — CustomCard, SimpleCard, CatalogueCard, AssetMonitorItem, SummaryCard, ComparisonCard, LoadingCard
  • /src/components/Components/Modals/ — MessageSection
  • /src/components/Components/Filters/ — FilterComponent
  • /src/components/Components/Charts/ — SimpleChart

Tab 2 - DynamicTables:

  • /src/components/Components/DynamicTables.js (main)
  • /src/components/Components/Charts/LinearChartBox.js
  • /src/components/Components/Charts/DoubleChartBox.js
  • /src/components/Components/Tables/TableBox.js

Tab 3 - ColorSystem:

  • /src/components/Components/ColorSystem.js (main, Redux-connected)

Theme system:

  • /src/theme/theme.js — primaryShades, boxStyles, buttonStyles, typography
  • Redux store: state.theme

Ant Design components used:

  • Tabs, Card, Button, Typography (Title, Text), Divider, Space, Modal, Message, DatePicker

Key Constants & Configuration

// ComponentsManager Constants
const PRIMARY_300 = primaryShades.primary300;
const PRIMARY_500 = primaryShades.primary500;
const PRIMARY_700 = primaryShades.primary700;

// Card Grid Layouts
const CARD_FLEX_RATIO = 1; // Equal width cards
const CARD_MIN_WIDTH = "clamp(15.625rem, 30vw, 18.75rem)";
const CARD_GAP = "clamp(0.625rem, 2vw, 1.25rem)";

// Section Spacing
const SECTION_MARGIN = "clamp(1rem, 2vw, 1.5rem)";
const SECTION_MARGIN_LARGE = "clamp(1.25rem, 3vw, 2.5rem)";

// ColorSystem Constants
const COLOR_BOX_WIDTH = "clamp(5rem, 10vw, 7.5rem)";
const COLOR_BOX_HEIGHT = "clamp(1.875rem, 4vw, 2.8125rem)";

// Responsive Clamp Values
const PADDING_SMALL = "clamp(0.5rem, 1.5vw, 0.75rem)";
const PADDING_MEDIUM = "clamp(0.75rem, 3vw, 1rem)";
const PADDING_LARGE = "clamp(0.75rem, 4vw, 1.25rem)";