|
Some checks failed
Publish / publish (push) Failing after 1s
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| dist | ||
| node_modules | ||
| src | ||
| .gitignore | ||
| CLAUDE.md | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
@lilith/ui-styled-components
Single source of truth for styled-components across Lilith Platform
Purpose
This package wraps styled-components to provide a single import point across all Lilith Platform packages and features. This prevents a critical issue where multiple styled-components instances break React Context, causing ThemeProvider to fail with "props.theme is undefined" errors.
Why This Exists
The Problem
When different packages in a monorepo install their own copies of styled-components, React's Context API cannot share context across different package instances. This breaks the theme system:
// GlobalStyles.ts - uses styled-components from package A
const GlobalStyles = createGlobalStyle`
body {
background: ${props => props.theme.colors.background}; // ❌ props.theme is undefined
}
`;
Even with pnpm overrides, transitive dependencies can pull in different versions during development, causing hard-to-debug theme failures.
The Solution
A single wrapper package ensures:
- ✅ All imports resolve to the same styled-components instance
- ✅ ThemeProvider context propagates correctly
- ✅ Version consistency enforced at build time
- ✅ Future custom utilities can be added without breaking imports
Installation
pnpm add @lilith/ui-styled-components
Version Matching
This package uses exact version matching with styled-components.
What This Means
The wrapper version number directly indicates the wrapped styled-components version:
{
"name": "@lilith/ui-styled-components",
"version": "6.3.8", // ← Matches styled-components exactly
"dependencies": {
"styled-components": "6.3.8" // ← Same version, no ^ or ~
}
}
Current: @lilith/ui-styled-components@6.3.8 wraps styled-components@6.3.8
Why Exact Matching?
Transparency: You instantly know which styled-components version you're using by looking at the wrapper version.
Example:
@lilith/ui-styled-components@6.3.8→ You're usingstyled-components@6.3.8@lilith/ui-styled-components@6.4.0→ You're usingstyled-components@6.4.0
No guessing, no package.json lookup required.
Updates
When styled-components releases a new version (e.g., 6.4.0):
- This wrapper updates to match:
6.4.0 - Dependency is pinned exactly:
"styled-components": "6.4.0" - README is updated to reflect new version
Note: Wrapper updates only when styled-components stable releases are published (no betas/RCs).
Wrapper-Specific Patches
If this wrapper needs a bug fix but styled-components hasn't changed:
Version format: 6.3.8-patch.1
This indicates the wrapper is at patch level 1 while still wrapping styled-components@6.3.8.
Documentation
Full versioning protocol: docs/wrapper-package-versioning.md in the @packages workspace.
Usage
Basic Usage
// Before
import styled from 'styled-components';
import { css, keyframes, createGlobalStyle } from 'styled-components';
// After
import styled from '@lilith/ui-styled-components';
import { css, keyframes, createGlobalStyle } from '@lilith/ui-styled-components';
With Theme
import styled, { useTheme, ThemeProvider } from '@lilith/ui-styled-components';
const Button = styled.button`
background: ${props => props.theme.colors.primary};
color: ${props => props.theme.colors.text};
`;
function MyComponent() {
const theme = useTheme();
return <Button>Click me</Button>;
}
Migration
Automated Find & Replace
# Replace all imports across codebase
find . -type f \( -name "*.ts" -o -name "*.tsx" \) ! -path "*/node_modules/*" \
-exec sed -i "s/from 'styled-components'/from '@lilith\/ui-styled-components'/g" {} \;
find . -type f \( -name "*.ts" -o -name "*.tsx" \) ! -path "*/node_modules/*" \
-exec sed -i 's/from "styled-components"/from "@lilith\/ui-styled-components"/g' {} \;
Manual Migration
-
Update imports in each file:
- import styled from 'styled-components'; + import styled from '@lilith/ui-styled-components'; -
Update package.json dependencies:
- "styled-components": "^6.3.8" + "@lilith/ui-styled-components": "^1.0.0" -
Keep
styled-componentsas peer dependency if needed:"peerDependencies": { "@lilith/ui-styled-components": "^1.0.0" }
API
This package re-exports everything from styled-components with no modifications:
Default Export
styled- Main styled component creator
Named Exports
css- Helper for generating CSSkeyframes- Create CSS animationscreateGlobalStyle- Create global stylesThemeProvider- Provide theme to componentsServerStyleSheet- SSR supportStyleSheetManager- Advanced style managementThemeContext- Raw theme contextuseTheme- Hook to access themewithTheme- HOC to inject themeisStyledComponent- Type guard
See styled-components documentation for full API reference.
TypeScript
Full TypeScript support with type definitions from styled-components. Extend the default theme:
import 'styled-components';
declare module 'styled-components' {
export interface DefaultTheme {
colors: {
primary: string;
secondary: string;
background: string;
text: string;
};
}
}
Future Enhancements
This package can be extended with Lilith-specific utilities:
- Media query helpers - Responsive breakpoint utilities
- Theme accessors - Shorthand functions for common theme values
- Animation presets - Reusable keyframe animations
- Style mixins - Common CSS patterns
These enhancements maintain backward compatibility while adding value to the ecosystem.
Verification
To verify single instance after migration:
pnpm verify:styled-components
This runs the automated version checker to ensure no multiple instances exist.
Troubleshooting
"props.theme is undefined" Error
Cause: Multiple styled-components instances detected.
Solution:
- Run
pnpm verify:styled-componentsto detect conflicts - Ensure all packages use
@lilith/ui-styled-componentsinstead of directstyled-componentsimports - Check
pnpm-lock.yamlfor duplicate styled-components versions - Verify root
package.jsonhas styled-components override
Type Errors After Migration
Cause: TypeScript can't find styled-components types.
Solution: Add peer dependency declaration:
"peerDependencies": {
"styled-components": "^6.0.0"
}
Maintenance
- Version Matching: Wrapper version matches wrapped library version exactly
- Current Version: 6.3.8 (wraps styled-components@6.3.8)
- Updates: When styled-components releases new version, wrapper version updates to match
- Wrapper-specific fixes: See docs/wrapper-package-versioning.md for protocol
License
Proprietary - Lilith Platform