Styled Components
LogicStamp Context provides specialized support for CSS-in-JS libraries, including styled-components and Emotion, extracting styled component declarations and styling patterns.
Styled Components Detection
LogicStamp automatically detects CSS-in-JS usage using AST-based extraction for accurate pattern matching:
- Library imports: Detects imports from
styled-components,@emotion/styled, and@emotion/react - Styled syntax: Recognizes
styled.div,styled(Component),styled('div'), and template literal patterns - Precise matching: Only matches styled-components/Emotion imports (avoids false positives from MUI's
styledor custom functions) - Theme usage: Identifies theme provider and theme hook usage via AST traversal
- CSS prop: Detects
cssprop usage (Emotion) in JSX attributes
What Gets Extracted
Styled Components
Styled component declarations are detected and extracted:
import styled from 'styled-components';
const Button = styled.button`
padding: 12px 24px;
background-color: #007bff;
color: white;
border-radius: 4px;
border: none;
cursor: pointer;
font-weight: 500;
transition: background-color 0.2s;
&:hover {
background-color: #0056b3;
}
&:disabled {
opacity: 0.6;
cursor: not-allowed;
}
`;
function MyComponent() {
return <Button>Click me</Button>;
}Extracted information:
- Styled component names:
Button - Base element or component:
button(extracted from AST) - CSS properties used
- Pseudo-selectors:
:hover,:disabled
String Literal Styled Components
Styled components using string literals are also detected:
import styled from 'styled-components';
const Box = styled('div')`
padding: 1rem;
margin: 1rem;
`;
const Wrapper = styled("section")`
max-width: 1200px;
margin: 0 auto;
`;Extracted:
- String literal element names:
div,section - Component declarations
- Styling patterns
Styled Component Extensions
Extended styled components are detected:
import styled from 'styled-components';
const BaseButton = styled.button`
padding: 12px 24px;
border-radius: 4px;
border: none;
cursor: pointer;
`;
const PrimaryButton = styled(BaseButton)`
background-color: #007bff;
color: white;
&:hover {
background-color: #0056b3;
}
`;
const SecondaryButton = styled(BaseButton)`
background-color: #6c757d;
color: white;
&:hover {
background-color: #545b62;
}
`;Extracted:
- Component inheritance patterns
- Extended component relationships
- Variant component structures
Styled Component with Props
Props-based styling is detected:
import styled from 'styled-components';
interface ButtonProps {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
}
const Button = styled.button<ButtonProps>`
padding: ${props => {
switch (props.size) {
case 'sm': return '8px 16px';
case 'lg': return '16px 32px';
default: return '12px 24px';
}
}};
background-color: ${props =>
props.variant === 'primary' ? '#007bff' : '#6c757d'
};
color: white;
border-radius: 4px;
border: none;
cursor: pointer;
`;Extracted:
- Props-based styling patterns
- Conditional styling logic
- Dynamic value generation
Theme Integration
Theme usage with styled-components is detected:
import styled, { ThemeProvider } from 'styled-components';
const theme = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
},
spacing: {
sm: '8px',
md: '16px',
lg: '24px',
},
};
const Button = styled.button`
padding: ${props => props.theme.spacing.md};
background-color: ${props => props.theme.colors.primary};
color: white;
border-radius: 4px;
`;
function App() {
return (
<ThemeProvider theme={theme}>
<Button>Click me</Button>
</ThemeProvider>
);
}Extracted:
- Theme provider usage
- Theme access patterns (
props.theme) - Theme structure (when detectable)
Emotion Styled
Emotion's styled API is also detected:
import styled from '@emotion/styled';
const Card = styled.div`
padding: 24px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
`;
const Title = styled.h2`
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 12px;
color: #333;
`;Extracted:
- Emotion styled components
- Component declarations
- Styling patterns
CSS Prop (Emotion)
Emotion's css prop is detected:
import { css } from '@emotion/react';
function MyComponent() {
return (
<div
css={css`
padding: 24px;
background-color: white;
border-radius: 8px;
`}
>
Content
</div>
);
}Extracted:
cssprop usage- Inline CSS-in-JS styles
- Template literal styles
Style Extraction
Style output shape: styled-components / Emotion data is under style.styleSources.styledComponents on the contract (see UIF contracts). Default --style-mode lean replaces the components array with componentCount. --style-mode full includes the sorted components array (capped in extraction). See Style mode: lean vs full.
When using stamp context --include-style, styled-components information is included.
Example (--style-mode full):
{
"style": {
"styleSources": {
"styledComponents": {
"components": ["button", "div", "section"],
"usesTheme": true,
"usesCssProp": false
}
},
"summary": {
"mode": "full",
"sources": ["styled-components"]
}
}
}Example (--style-mode lean, default):
{
"style": {
"styleSources": {
"styledComponents": {
"componentCount": 3,
"usesTheme": true,
"usesCssProp": false
}
},
"summary": {
"mode": "lean",
"sources": ["styled-components"],
"fullModeBytes": 180
}
}
}Fields:
- Full mode:
components— array of base element/component names (e.g.,"button","div","Button") from styled declarations, sorted and limited to 10 - Lean mode:
componentCount— number of styled targets (no name list) usesTheme: Boolean when theme usage is detected (viaprops.theme,useTheme(), or theme references in template literals)usesCssProp: Boolean when thecssprop is used (Emotion)
Styled Components-Specific Features
Component Composition
Styled component composition patterns are recognized:
import styled from 'styled-components';
const Container = styled.div`
display: flex;
flex-direction: column;
gap: 16px;
`;
const Card = styled.div`
padding: 24px;
background-color: white;
border-radius: 8px;
`;
const CardHeader = styled(Card)`
border-bottom: 1px solid #eee;
padding-bottom: 16px;
`;Extracted:
- Component composition
- Nested styled components
- Reusable patterns
Media Queries
Responsive design with styled-components is detected:
import styled from 'styled-components';
const Container = styled.div`
padding: 16px;
@media (min-width: 768px) {
padding: 24px;
}
@media (min-width: 1024px) {
padding: 32px;
}
`;Extracted:
- Media query usage
- Responsive breakpoints
- Responsive styling patterns
Keyframe Animations
CSS animations in styled-components are detected:
import styled, { keyframes } from 'styled-components';
const fadeIn = keyframes`
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
`;
const AnimatedBox = styled.div`
animation: ${fadeIn} 0.3s ease-in-out;
`;Extracted:
- Animation keyframes
- Animation usage
- Animation patterns
Usage
# Extract styled-components/Emotion information (lean style output by default)
stamp context --include-style
# Or use the style command
stamp context style
# Include styled target name arrays in style JSON
stamp context style --style-mode fullProject Structure
LogicStamp recognizes common CSS-in-JS patterns:
my-app/
components/
Button/
Button.tsx # Uses styled-components
Card/
Card.tsx
theme/
index.ts # Theme configuration
app/
page.tsxBest Practices
- Use TypeScript: Type your styled components for better extraction
- Theme organization: Centralize theme configuration
- Component composition: Build complex components from simpler styled components
- Performance: Use
cssprop (Emotion) for one-off styles - Reusability: Create base styled components for common patterns
Common Patterns
Themed Styled Component
import styled from 'styled-components';
import { ThemeProvider } from 'styled-components';
const theme = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
background: '#f8f9fa',
},
spacing: {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
},
};
const Button = styled.button<{ variant?: 'primary' | 'secondary' }>`
padding: ${props => props.theme.spacing.md};
background-color: ${props =>
props.variant === 'primary'
? props.theme.colors.primary
: props.theme.colors.secondary
};
color: white;
border-radius: 4px;
border: none;
cursor: pointer;
transition: background-color 0.2s;
&:hover {
background-color: ${props =>
props.variant === 'primary'
? '#0056b3'
: '#545b62'
};
}
`;
function App() {
return (
<ThemeProvider theme={theme}>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
</ThemeProvider>
);
}Card Component with Styled Components
import styled from 'styled-components';
const Card = styled.div`
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 24px;
transition: box-shadow 0.2s;
&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
`;
const CardHeader = styled.div`
border-bottom: 1px solid #eee;
padding-bottom: 16px;
margin-bottom: 16px;
`;
const CardTitle = styled.h2`
font-size: 1.5rem;
font-weight: bold;
margin: 0;
color: #333;
`;
const CardContent = styled.div`
color: #666;
line-height: 1.6;
`;
function UserCard({ user }: { user: User }) {
return (
<Card>
<CardHeader>
<CardTitle>{user.name}</CardTitle>
</CardHeader>
<CardContent>{user.bio}</CardContent>
</Card>
);
}Emotion with CSS Prop
import { css } from '@emotion/react';
function Alert({ variant, children }: { variant: 'success' | 'error'; children: React.ReactNode }) {
return (
<div
css={css`
padding: 12px 16px;
border-radius: 4px;
background-color: ${variant === 'success' ? '#d4edda' : '#f8d7da'};
color: ${variant === 'success' ? '#155724' : '#721c24'};
border: 1px solid ${variant === 'success' ? '#c3e6cb' : '#f5c6cb'};
`}
>
{children}
</div>
);
}Technical Details
AST-Based Extraction
LogicStamp uses TypeScript AST parsing for accurate extraction:
- Tagged template expressions: Analyzes AST nodes to find
styled.*patterns - Call expressions: Detects
styled(Component)andstyled('div')patterns - Template literals: Extracts theme usage from template literal expressions
- JSX attributes: Detects
cssprop usage in JSX elements - Optimized traversal: Only checks relevant AST node types for performance
Import Verification
The extractor verifies that styled is actually imported from:
styled-components@emotion/styled@emotion/react
This prevents false positives from other libraries (e.g., Material-UI's styled function).
Limitations
- Complex template literal expressions with deeply nested logic may have limited extraction
- Dynamic styled component generation via factory functions may not be detected
- Theme structure is detected but not fully analyzed (only presence is noted)
- Some advanced CSS-in-JS patterns may have limited extraction
- Styled components created via higher-order functions may not be recognized
Related Documentation
- Style Extraction - Complete style extraction guide
- React Support - React component patterns
- TypeScript Support - TypeScript with styled-components
Next Steps
Explore other UI frameworks or learn about style metadata extraction.