atomic-ui-core-css
v1.0.0
Published
is a conceptual, powerful, and highly flexible CSS tool designed to revolutionize how you build user interfaces. It combines the best aspects of utility-first CSS with modern TypeScript capabilities, robust theming, and a strong focus on performance and a
Maintainers
Readme
# `atomic-ui-core-css`
[](https://www.npmjs.com/package/atomic-ui-core-css)
[](LICENSE)
**`atomic-ui-core-css`** is a conceptual, powerful, and highly flexible CSS tool designed to revolutionize how you build user interfaces. It combines the best aspects of utility-first CSS with modern TypeScript capabilities, robust theming, and a strong focus on performance and accessibility.
## 🌟 Philosophy
`atomic-ui-core-css` aims to solve the common drawbacks of existing CSS frameworks by:
* **Empowering Granular Control:** Providing a comprehensive set of atomic utility classes for precise styling.
* **Ensuring Type Safety:** Leveraging TypeScript to guide your styling choices directly in your code, reducing errors and improving developer experience.
* **Promoting Semantic Design:** Basing all styling on configurable design tokens (CSS variables) for easy theming and consistent branding.
* **Delivering Peak Performance:** Utilizing Just-In-Time (JIT) compilation and intelligent purging to generate the smallest possible CSS bundles.
* **Building Accessibility In:** Offering utilities and patterns that inherently make your UI accessible.
* **Maintaining Framework Agnosticism:** Providing a core CSS foundation that can be seamlessly integrated with any JavaScript framework (React, Angular, Vue, Next.js, etc.) through thin, optional adapters.
## ✨ Core Concepts & Features
1. **Semantic Design Tokens (`src/config.ts`):**
* All colors, spacing, typography, breakpoints, etc., are defined in a central configuration file using semantic names (e.g., `primary-500`, `text-default`, `space-4`).
* These tokens are automatically transformed into CSS Custom Properties (CSS Variables) at build time, allowing for dynamic, runtime theming.
2. **Type-Driven Styling (`src/types/utility-types.ts`):**
* The core innovation: Instead of remembering countless class names, you apply styles using a strongly-typed `AtomicUIProps` interface directly in your JSX/TSX.
* This provides **autocomplete**, **type checking**, and **inline documentation** for all styling properties, significantly boosting developer experience and reducing errors.
* *(Conceptual Implementation: A build-time Babel/SWC plugin or a framework-specific adapter would transform these typed props into actual CSS class names for the final output.)*
3. **Atomic CSS Generation (`src/postcss-plugin.ts`):**
* A powerful PostCSS plugin processes your configuration and scanned usage to generate highly optimized, single-purpose CSS utility classes (e.g., `.flex`, `.p-4`, `.text-primary-500`).
* It intelligently purges unused CSS, ensuring your production bundle contains only the styles you actually need.
* Supports responsive variants (e.g., `sm:flex`, `md:text-lg`) and pseudo-classes (`hover:bg-primary-600`).
4. **Robust Runtime Theming (`src/runtime/theme-switcher.ts`):**
* Leverages CSS variables for dynamic theming. You can define multiple themes (light, dark, custom brand) by simply changing the values of CSS variables, often by toggling a `data-theme` attribute on the `<html>` element.
* The `ThemeSwitcher` utility provides a simple API for managing this client-side.
5. **Built-in Accessibility Primitives:**
* Includes essential accessibility utilities like `sr-only` (visually hidden, but available to screen readers) and encourages patterns for accessible focus management.
* The type-driven approach can guide developers towards accessible styling choices.
6. **Framework-Agnostic Core:**
* The generated CSS is plain CSS, compatible with any web project.
* The TypeScript types (`AtomicUIProps`) provide a universal interface.
* Thin, optional adapters (e.g., a React hook `useAtomicStyles` or an Angular directive) would provide the best DX for specific frameworks, translating the typed props into the generated class names.
## 🚀 Installation (Conceptual)
```bash
npm install atomic-ui-core-css postcss
# For React/Next.js:
# npm install @atomic-ui/react-adapter # (Conceptual)You would then configure your build system (e.g., Webpack, Vite, Next.js, Angular CLI) to use the atomic-ui-core-css PostCSS plugin.
📚 Usage (Conceptual)
1. Configuration (postcss.config.js or tailwind.config.js-like)
// postcss.config.js
const atomicUIPostcssPlugin = require('atomic-ui-core-css').atomicUIPostcssPlugin;
const defaultAtomicUIConfig = require('atomic-ui-core-css').defaultAtomicUIConfig;
module.exports = {
plugins: [
atomicUIPostcssPlugin({
config: {
// Override or extend defaultAtomicUIConfig here
colors: {
...defaultAtomicUIConfig.colors,
'brand-primary': '#FF5733',
},
spacing: {
...defaultAtomicUIConfig.spacing,
'7': '28px',
}
},
purge: {
content: [
'./src/**/*.{html,js,jsx,ts,tsx,vue}', // Scan these files for utility usage
],
},
outputCssVariables: true, // Output :root variables for theming
}),
// ... other PostCSS plugins like autoprefixer
],
};2. Styling in your Component (e.g., React/TSX)
Imagine a framework adapter (or a simple helper) that consumes AtomicUIProps:
// components/Button.tsx (React example with conceptual 'aui' prop)
import React from 'react';
import { AtomicUIProps, Colors, Spacing } from 'atomic-ui-core-css';
// In a real adapter, 'aui' would be a function/hook that generates class names
// For this example, we'll assume it magically converts props to classes.
// const aui = (props: AtomicUIProps) => generateAtomicClasses(props); // From src/index.ts
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'ghost';
size?: 'sm' | 'md' | 'lg';
children: React.ReactNode;
// Direct styling props from AtomicUIProps for granular control
aui?: AtomicUIProps;
}
const Button: React.FC<ButtonProps> = ({ variant = 'primary', size = 'md', children, aui: customAuiProps, ...rest }) => {
let baseStyles: AtomicUIProps = {
display: 'inline-flex',
align: 'center',
justify: 'center',
fontWeight: 'medium',
borderRadius: 'base',
_focus: { shadow: 'base', borderColor: 'primary-300' }, // Accessible focus ring
_hover: {}, // Placeholder for hover styles
p: { base: '2', sm: '3' }, // Responsive padding
fontSize: { base: 'sm', md: 'base' } // Responsive font size
};
switch (variant) {
case 'primary':
baseStyles = {
...baseStyles,
bgColor: 'primary-500',
textColor: 'text-inverted',
_hover: { bgColor: 'primary-600' },
};
break;
case 'secondary':
baseStyles = {
...baseStyles,
bgColor: 'secondary-500',
textColor: 'text-inverted',
_hover: { bgColor: 'secondary-600' },
};
break;
case 'ghost':
baseStyles = {
...baseStyles,
bgColor: 'transparent',
textColor: 'text-default',
_hover: { bgColor: 'neutral-100' },
};
break;
}
switch (size) {
case 'sm':
baseStyles = { ...baseStyles, p: '1', fontSize: 'xs' };
break;
case 'lg':
baseStyles = { ...baseStyles, p: '4', fontSize: 'lg' };
break;
}
// Merge default/variant styles with custom props
const finalAuiProps: AtomicUIProps = { ...baseStyles, ...customAuiProps };
// This is the conceptual part: generateAtomicClasses would turn finalAuiProps
// into a string of class names like "flex items-center p-2 sm:p-3 bg-primary-500 ..."
// In a real setup, this might be a Babel/SWC transform or a runtime utility.
const className = generateAtomicClasses(finalAuiProps); // Using the exported helper from src/index.ts
return (
<button className={className} {...rest}>
{children}
</button>
);
};
export default Button;
// --- Example Usage in another component ---
// import Button from './Button';
// import { ThemeSwitcher } from 'atomic-ui-core-css';
// const themeSwitcher = new ThemeSwitcher();
// const MyComponent = () => {
// return (
// <div className={generateAtomicClasses({ p: '8', bgColor: 'bg-default', textColor: 'text-default', shadow: 'md', borderRadius: 'lg' })}>
// <h1 className={generateAtomicClasses({ fontSize: '3xl', fontWeight: 'bold', mb: '4' })}>Welcome to Atomic UI!</h1>
// <p className={generateAtomicClasses({ mb: '6', textColor: 'text-light' })}>
// This is a demonstration of a powerful, type-driven CSS tool.
// </p>
// <div className={generateAtomicClasses({ display: 'flex', gap: '3' })}>
// <Button variant="primary" size="lg">Get Started</Button>
// <Button variant="secondary" aui={{ shadow: 'sm', _hover: { shadow: 'base' } }}>Learn More</Button>
// <Button variant="ghost" aui={{ srOnly: true }}>Hidden Button</Button>
// </div>
// <button
// className={generateAtomicClasses({ mt: '6', p: '2', bgColor: 'neutral-200', borderRadius: 'base' })}
// onClick={() => themeSwitcher.toggleTheme('light', 'dark')}
// >
// Toggle Theme ({themeSwitcher.getCurrentTheme()})
// </button>
// </div>
// );
// };
// export default MyComponent;3. Runtime Theming (in your main HTML/JS)
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Atomic UI App</title>
<!-- Your generated CSS file (e.g., main.css) would be linked here -->
<link rel="stylesheet" href="/dist/main.css">
<style>
/* Define your base theme variables (light theme by default) */
:root {
--aui-color-primary-500: #6366F1;
--aui-color-neutral-700: #404040;
--aui-color-bg-default: #FAFAFA;
--aui-color-neutral-100: #F5F5F5;
--aui-color-neutral-300: #D4D4D4;
--aui-color-neutral-50: #FAFAFA;
/* ... all other base variables from defaultAtomicUIConfig */
}
/* Define your dark theme variables, applied when data-aui-theme="dark" */
html[data-aui-theme="dark"] {
--aui-color-primary-500: #818CF8; /* Lighter primary for dark mode */
--aui-color-neutral-700: #D4D4D4; /* Lighter text for dark mode */
--aui-color-bg-default: #171717; /* Dark background */
--aui-color-neutral-100: #262626; /* Darker surface */
--aui-color-neutral-300: #525252; /* Darker border */
--aui-color-neutral-50: #171717; /* Darker neutral-50 for bg-default */
}
</style>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.ts"></script>
<script type="module">
// Basic setup for ThemeSwitcher
import { ThemeSwitcher } from './dist/index.js'; // Adjust path based on your build output
const themeSwitcher = new ThemeSwitcher();
// You can expose it globally or use it within your framework's context
window.themeSwitcher = themeSwitcher;
</script>
</body>
</html>📈 Benefits & How it Addresses Requirements
Greater Flexibility and Granular Control:
- Atomic Utilities: Provides the fine-grained control of Tailwind, allowing you to build any design.
- Semantic Tokens: While using atomic classes, their values are derived from semantic tokens, allowing global changes from a single source.
Smaller Bundle Sizes and Better Performance Optimization:
- JIT Compilation & Purging: The PostCSS plugin ensures that only the CSS utilities actually used in your project are included in the final bundle, leading to extremely small CSS files.
- CSS Variables: Reduce duplication in the final CSS output, as values are defined once and referenced.
Improved Developer Experience (DX) and Less Boilerplate:
- Type-Driven Styling: This is the game-changer. Developers get full TypeScript autocomplete, type checking, and inline documentation for all styling props directly in their JSX/TSX. No more guessing class names or constantly referencing documentation.
- Less Context Switching: Style directly in your component file, guided by types.
- Composable Components: Encourages building reusable components by composing
AtomicUIProps, reducing repetitive class strings in markup.
Enhanced Accessibility Out-of-the-Box or with Better Tooling:
- Built-in Accessibility Utilities: Provides utilities like
sr-onlyand encourages accessible focus management patterns. - Semantic Token Usage: Promotes consistent color contrast and typography.
- Type Guidance: The type system can be extended to guide accessible prop usage (e.g., ensuring
aria-*attributes are used correctly with certain components).
- Built-in Accessibility Utilities: Provides utilities like
More Robust Theming Capabilities (Runtime Theming):
- CSS Variables: The entire design system is built on CSS custom properties, allowing for instant, runtime theme switching by simply changing a
data-aui-themeattribute on the<html>element. No recompilation needed for theme changes. - Semantic Aliases:
text-default,bg-surfaceprovide a high-level abstraction that maps to the underlying color palette, making theme definitions clear.
- CSS Variables: The entire design system is built on CSS custom properties, allowing for instant, runtime theme switching by simply changing a
Bridging the Gap Between Compile-time TypeScript and Runtime Needs:
- The
AtomicUIPropsinterface (compile-time) directly informs thegenerateAtomicClassesfunction (runtime/build-time transformation). This ensures that what you type-check at compile time is what's generated and applied at runtime. - This is the core of "Type-Driven Styling."
- The
Framework-Agnostic Core Logic for UI Patterns:
- The generated CSS and the
AtomicUIPropsinterface are framework-agnostic. - The
generateAtomicClassesfunction can be used by any framework's component system (e.g., a React hook, an Angular directive, a Vue component prop). This allows for maximum flexibility and reusability across different frontend stacks.
- The generated CSS and the
This conceptual atomic-ui-core-css package represents a significant leap forward by integrating design tokens, utility-first principles, strong TypeScript typing, and advanced build-time optimizations into a cohesive and powerful CSS tool. Implementing the full PostCSS plugin and framework adapters would be a substantial project, but the architecture lays out a clear path to achieve these highly desired features while addressing the requirements of modern web development.
