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
- Use Garden Components: Prefer Garden components over custom implementations for consistency
- Theme Consistency: Use PALETTE colors instead of hardcoded hex values
- Component Encapsulation: Keep styles scoped to their components using styled-components
- Responsive Design: Use Garden's Grid system and media queries for responsiveness
- 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
Modal Component
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>
);