Skip to main content
Version: 3.2.x

Styling Guide

Overview

This document provides an overview of the styling approach used in the Optave ZCLI project.

Styling Architecture

The project uses a component-based styling approach with these key technologies:

  • Styled Components: Primary styling solution using CSS-in-JS
  • Zendesk Garden Design System: Provides consistent UI components and theming
  • Global CSS: Limited global styles in index.css

Zendesk Garden Integration

The project heavily relies on Zendesk Garden components for consistent UI:

import { ThemeProvider, PALETTE } from '@zendeskgarden/react-theming';
import { Grid, Row, Col } from '@zendeskgarden/react-grid';
import { LG, MD } from '@zendeskgarden/react-typography';
import { Button } from '@zendeskgarden/react-buttons';

Key Garden packages used:

  • @zendeskgarden/react-theming: Provides theming capabilities
  • @zendeskgarden/react-grid: Layout components (Grid, Row, Col)
  • @zendeskgarden/react-typography: Text styling components
  • @zendeskgarden/react-buttons: Button components
  • @zendeskgarden/react-forms: Form elements
  • @zendeskgarden/react-modals: Modal dialogs
  • @zendeskgarden/react-tooltips: Tooltip components
  • @zendeskgarden/svg-icons: Iconography

Color System

Garden PALETTE

Garden's PALETTE object provides a standardized color system:

import { PALETTE } from '@zendeskgarden/react-theming';

// Examples
const darkText = PALETTE.grey[800];
const primaryBlue = PALETTE.blue[600];
const successGreen = PALETTE.green[600];

Custom Colors

Custom colors are defined in src/constants/colours.ts:

// Custom color constants
export const AGENT_BAR_COLOUR = '#1F73B7';
export const AI_BAR_COLOUR = '#ADCCE4';
export const PIE_CHART_BLUE = '#349EFF';
export const PIE_CHART_GREEN = '#19b75e';
export const PIE_CHART_YELLOW = '#FFCE56';
export const PIE_CHART_BROWN = '#E09846';

Component Styling

Components are styled using the styled-components library:

import styled from 'styled-components';

const StyledContainer = styled.div`
display: flex;
flex-direction: column;
padding: 16px;
border-radius: 4px;
background-color: ${PALETTE.white};
`;

// With conditional styling based on props
const StyledButton = styled.button<{ isActive: boolean }>`
background-color: ${props => props.isActive ? PALETTE.blue[600] : PALETTE.grey[200]};
color: ${props => props.isActive ? PALETTE.white : PALETTE.grey[800]};
`;

Layout System

The project uses Zendesk Garden's grid system for responsive layouts:

<ThemeProvider>
<Grid>
<Row>
<Col sm={12} md={6} lg={4}>
{/* Content */}
</Col>
<Col sm={12} md={6} lg={8}>
{/* Content */}
</Col>
</Row>
</Grid>
</ThemeProvider>

Typography

Text styling is managed through Garden typography components:

import { LG, MD, SM, XL } from '@zendeskgarden/react-typography';

// Usage
<XL>Heading text</XL>
<LG>Subheading text</LG>
<MD>Normal text</MD>
<SM>Small text</SM>

Global Styles

Limited global styles are defined in src/app/index.css:

  • Base HTML element styles
  • Custom scrollbar styling
  • Color scheme preferences
  • Root layout container styles

Best Practices

  1. Use Garden Components: Prefer Garden components over custom implementations for consistency
  2. Theme Consistency: Use PALETTE colors instead of hardcoded hex values
  3. Component Encapsulation: Keep styles scoped to their components using styled-components
  4. Responsive Design: Use Garden's Grid system and media queries for responsiveness
  5. Prop-Based Styling: Utilize component props to control styling variations

Icon Usage

The project uses Zendesk Garden SVG icons:

import PencilStroke from '@zendeskgarden/svg-icons/src/12/pencil-stroke.svg';
import InfoStroke from '@zendeskgarden/svg-icons/src/16/info-stroke.svg';

Examples

import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Modal, Header, Body, Footer, Close } from '@zendeskgarden/react-modals';
import { Button } from '@zendeskgarden/react-buttons';
import styled from 'styled-components';

const StyledModalBody = styled(Body)`
padding: 24px;
max-height: 70vh;
overflow-y: auto;
`;

const StyledFooter = styled(Footer)`
justify-content: space-between;
`;

const CustomModal = ({ isOpen, onClose, title, children }) => (
<ThemeProvider>
<Modal isOpen={isOpen} onClose={onClose}>
<Header>{title}</Header>
<Close aria-label="Close modal" />
<StyledModalBody>{children}</StyledModalBody>
<StyledFooter>
<Button onClick={onClose}>Cancel</Button>
<Button isPrimary>Save</Button>
</StyledFooter>
</Modal>
</ThemeProvider>
);