A modern approach to React component development with support for multiple styling systems and automatic CSS generation.
- Multiple Styling Systems: Support for Quark (atomic) and Semantic class naming
- Automatic Parsing: Extract classes from components using RegEx
- CSS Generation: Automatic creation of optimized stylesheets
- Headless Components: Base components without styles
- TypeScript: Full type support
packages/
├── ui-parser/ # CLI utility for analysis and transformation
├── ui-headless/ # Base unstyled components
└── app/ # Demo application
bun install
# Analyze components and extract classes
bun ui-parser:analyze -s ./src/source -o ./src/components
# Generate CSS files
bun ui-parser:generate -s ./src/source -o ./src/styles
# Transform components to Quark/Semantic versions
bun ui-parser:transform -s ./src/source -o ./src/components
# Run all steps in sequence
bun ui-parser:all -s ./src/source -o ./src/components
The RegEx adapter automatically extracts classes from your components by analyzing:
- JSX className attributes
- Tailwind class constants
- tailwind-variants configurations
- Dynamic class expressions
- Template literals
Example component:
const buttonVariants = tv({
base: "rounded-md px-4 py-2",
variants: {
size: {
sm: "text-sm",
lg: "text-lg"
}
}
});
export function Button({ size }) {
return (
<button className={buttonVariants({ size })}>
Click me
</button>
);
}
The adapter will extract all classes and generate both Quark and Semantic versions.
For each component, UI Parser generates:
-
Quark Version (
ComponentName.quark.tsx
)- Uses atomic class names
- Optimized for reusability
- Example:
flex items-center justify-between
-
Semantic Version (
ComponentName.semantic.tsx
)- Uses semantic class names
- Better readability
- Example:
header-container
-
CSS Files
quark.css
: Atomic stylessemantic.css
: Semantic styles
Import styles in your main CSS file:
/* Base styles */
@import "./styles/base.css";
/* Components */
@import "./styles/components/navigation.css";
/* Semantic */
@import "./components/semantic.css";
/* Quark */
@import "./components/quark.css";
Use components in your application:
import { HeroSplitQuark } from "@/components/HeroSplit.quark";
import { HeroSplitSemantic } from "@/components/HeroSplit.semantic";
import { HeroSplit } from "@/source/HeroSplit";
export default function App() {
return (
<div className="font-sans bg-background text-foreground antialiased">
<div className="container mx-auto px-4">
{/* Original component */}
<HeroSplit />
{/* Quark version */}
<HeroSplitQuark />
{/* Semantic version */}
<HeroSplitSemantic />
</div>
</div>
);
}
The @ui-headless
package provides unstyled base components that can be used as a foundation for your styled components.
- Zero default styles
- Full accessibility support
- Flexible composition with Slot pattern
- Complete TypeScript types
Button
: Base button component with ref forwardingSlot
: Component composition utility- More components coming soon...
import { Button } from "@ui-factory/ui-headless";
// Use with Quark classes
export function PrimaryButton({ children }) {
return (
<Button className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
{children}
</Button>
);
}
// Use with Semantic classes
export function SecondaryButton({ children }) {
return (
<Button className="button-secondary">
{children}
</Button>
);
}
The Slot component allows you to compose components while maintaining proper prop and ref forwarding:
import { Slot } from "@ui-factory/ui-headless";
export function Container({ asChild, children, ...props }) {
return (
<Slot asChild={asChild} {...props}>
{children}
</Slot>
);
}
Contributions are welcome! Please read our contributing guidelines for details.
MIT