Skip to content

Latest commit

 

History

History
212 lines (167 loc) · 4.76 KB

File metadata and controls

212 lines (167 loc) · 4.76 KB

MQTT Explorer Styling Conventions

This document outlines the styling conventions used in MQTT Explorer for visual consistency and maintainable code.

UI Framework

Material-UI (MUI) v7 with JSS styling via withStyles HOC.

Stack:

  • @mui/material (v7) - Core components and theming
  • @mui/icons-material (v7) - Icons
  • @mui/styles (v6) - JSS styling with withStyles
  • @emotion/react & @emotion/styled - CSS-in-JS foundation

Theming

Location: app/src/theme.ts

Configuration:

  • Light and dark modes supported
  • Primary color: #335C67 (teal/blue-green)
  • Secondary: Material-UI amber palette
  • Base typography: 0.9rem, userSelect: 'none'

Application:

<ThemeProvider theme={theme}>
  <LegacyThemeProvider theme={theme}>
    <App />
  </LegacyThemeProvider>
</ThemeProvider>

Colors

Access theme colors:

backgroundColor: theme.palette.background.default
color: theme.palette.text.primary
borderColor: theme.palette.divider

Material-UI palettes:

import { blueGrey, amber, green, red, orange } from '@mui/material/colors'
backgroundColor: blueGrey[100]  // Light shade
backgroundColor: blueGrey[700]  // Dark shade

Theme-conditional:

const color = theme.palette.mode === 'light' ? blueGrey[300] : theme.palette.primary.main

Code editor colors: Defined in app/src/components/Sidebar/CodeBlockColors.ts

Typography

Variants:

<Typography variant="h6">Heading</Typography>
<Typography variant="body1">Body text</Typography>
<Typography variant="caption">Caption</Typography>

Font sizes:

fontSize: theme.typography.pxToRem(15)

Monospace: "12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace"

Spacing

8px grid system:

margin: theme.spacing(1)      // 8px
padding: theme.spacing(2)     // 16px
marginLeft: theme.spacing(1.5) // 12px (tree indentation)

Border radius:

borderRadius: theme.shape.borderRadius  // 4px default

Component Styling

Primary approach - withStyles HOC:

import { withStyles } from '@mui/styles'
import { Theme } from '@mui/material/styles'

const styles = (theme: Theme) => ({
  root: {
    backgroundColor: theme.palette.background.default,
    padding: theme.spacing(2),
  },
})

export default withStyles(styles)(MyComponent)

Type assertions:

display: 'block' as 'block'
whiteSpace: 'nowrap' as 'nowrap'
overflow: 'hidden' as 'hidden'

Responsive:

[theme.breakpoints.up(750)]: {
  display: 'block',
}

sx prop (simple cases):

<Button sx={{ color: 'primary.contrastText' }}>Text</Button>

Animations

CSS animations:

animation: 'updateLight 0.5s'

Theme transitions:

transition: theme.transitions.create('transform', {
  easing: theme.transitions.easing.sharp,
  duration: theme.transitions.duration.leavingScreen,
})

Interactive States

Hover:

'&:hover': {
  backgroundColor: theme.palette.mode === 'light' 
    ? blueGrey[100] 
    : theme.palette.primary.light,
}

Selection:

selected: {
  backgroundColor: (theme.palette.mode === 'light' 
    ? blueGrey[300] 
    : theme.palette.primary.main) + ' !important',
}

Common Patterns

Tree nodes:

node: {
  overflow: 'hidden',
  textOverflow: 'ellipsis',
  whiteSpace: 'nowrap',
}
subnodes: {
  marginLeft: theme.spacing(1.5),
}

Buttons:

<Button variant="contained" color="primary">Submit</Button>
<Button variant="outlined" color="primary">Cancel</Button>
<Button>Learn More</Button>

Icons:

<Icon fontSize="inherit" />
<Icon style={{ fontSize: '16px' }} />

Best Practices

DO: ✅ Use theme variables (theme.palette.*, theme.spacing(), theme.typography.*) ✅ Use withStyles HOC for component styles ✅ Use theme.palette.mode for light/dark conditional styling ✅ Import Material-UI color palettes for extended colors ✅ Keep styles co-located with components

DON'T: ❌ Hardcode colors or spacing values ❌ Create global CSS files ❌ Duplicate style definitions ❌ Use inline styles for complex patterns

Resources

Testing: Verify in both light/dark themes, check responsive behavior, ensure accessibility.

Related