@ordojs/core
Version:
Core compiler and runtime for OrdoJS framework
500 lines (469 loc) • 13.9 kB
JavaScript
/**
* @fileoverview CSS Framework Integration for OrdoJS Framework
* Handles integration with external CSS frameworks like Tailwind CSS
*/
import { promises as fs } from 'fs';
import path from 'path';
/**
* CSS Framework Integration Manager
*/
export class OrdoJSCSSFrameworkIntegration {
options;
constructor(options) {
this.options = {
includeFrameworkCSS: true,
purgeUnused: true,
generateSourceMaps: false,
minify: false,
contentPaths: [],
...options
};
}
/**
* Integrate CSS framework with OrdoJS
*/
async integrate() {
try {
switch (this.options.framework) {
case 'tailwind':
return await this.integrateTailwind();
case 'bootstrap':
return await this.integrateBootstrap();
case 'bulma':
return await this.integrateBulma();
case 'foundation':
return await this.integrateFoundation();
case 'custom':
return await this.integrateCustom();
default:
throw new Error(`Unsupported CSS framework: ${this.options.framework}`);
}
}
catch (error) {
return {
css: '',
cssPath: '',
success: false,
errors: [error instanceof Error ? error.message : String(error)]
};
}
}
/**
* Integrate Tailwind CSS
*/
async integrateTailwind() {
const tailwindConfig = this.generateTailwindConfig();
const cssContent = this.generateTailwindCSS(tailwindConfig);
return {
css: cssContent,
cssPath: 'styles/tailwind.css',
success: true,
metadata: {
framework: 'tailwind',
version: '3.x',
config: tailwindConfig
}
};
}
/**
* Generate Tailwind CSS configuration
*/
generateTailwindConfig() {
return {
content: [
'./src/**/*.ordo',
'./src/**/*.html',
'./src/**/*.js',
'./src/**/*.ts',
...this.options.contentPaths || []
],
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
}
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
spacing: {
'18': '4.5rem',
'88': '22rem',
}
}
},
plugins: [
// These will be available after npm install
// require('@tailwindcss/forms'),
// require('@tailwindcss/typography'),
// require('@tailwindcss/aspect-ratio'),
],
corePlugins: {
preflight: true,
}
};
}
/**
* Generate Tailwind CSS content
*/
generateTailwindCSS(config) {
return ` base;
components;
utilities;
/* OrdoJS Tailwind Integration */
base {
/* Custom base styles */
html {
scroll-behavior: smooth;
}
body {
antialiased;
}
}
components {
/* OrdoJS component styles */
.ordojs-component {
relative;
}
.ordojs-button {
px-4 py-2 rounded-md font-medium transition-colors duration-200;
}
.ordojs-button-primary {
bg-primary-600 text-white hover:bg-primary-700 focus:ring-2 focus:ring-primary-500 focus:ring-offset-2;
}
.ordojs-button-secondary {
bg-gray-200 text-gray-900 hover:bg-gray-300 focus:ring-2 focus:ring-gray-500 focus:ring-offset-2;
}
.ordojs-input {
block w-full rounded-md border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm;
}
.ordojs-card {
bg-white overflow-hidden shadow rounded-lg;
}
.ordojs-card-header {
px-4 py-5 sm:px-6 border-b border-gray-200;
}
.ordojs-card-body {
px-4 py-5 sm:p-6;
}
.ordojs-card-footer {
px-4 py-4 sm:px-6 border-t border-gray-200;
}
}
utilities {
/* OrdoJS utility classes */
.ordojs-text-gradient {
bg-gradient-to-r from-primary-600 to-purple-600 bg-clip-text text-transparent;
}
.ordojs-bg-gradient {
bg-gradient-to-r from-primary-600 to-purple-600;
}
.ordojs-shadow-glow {
shadow-lg shadow-primary-500/25;
}
}`;
}
/**
* Integrate Bootstrap
*/
async integrateBootstrap() {
const cssContent = `/* Bootstrap CSS */
url('https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css');
/* OrdoJS Bootstrap Integration */
.ordojs-component {
position: relative;
}
.ordojs-button {
display: inline-block;
font-weight: 400;
text-align: center;
vertical-align: middle;
cursor: pointer;
padding: 0.375rem 0.75rem;
font-size: 1rem;
line-height: 1.5;
border-radius: 0.25rem;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.ordojs-button-primary {
color: #fff;
background-color: #0d6efd;
border-color: #0d6efd;
}
.ordojs-button-primary:hover {
color: #fff;
background-color: #0b5ed7;
border-color: #0a58ca;
}
.ordojs-input {
display: block;
width: 100%;
padding: 0.375rem 0.75rem;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: 0.25rem;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.ordojs-input:focus {
color: #212529;
background-color: #fff;
border-color: #86b7fe;
outline: 0;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}`;
return {
css: cssContent,
cssPath: 'styles/bootstrap.css',
success: true,
metadata: {
framework: 'bootstrap',
version: '5.3.0'
}
};
}
/**
* Integrate Bulma
*/
async integrateBulma() {
const cssContent = `/* Bulma CSS */
url('https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css');
/* OrdoJS Bulma Integration */
.ordojs-component {
position: relative;
}
.ordojs-button {
display: inline-block;
padding: 0.5em 1em;
margin: 0;
border: 1px solid transparent;
border-radius: 4px;
font-size: 1rem;
line-height: 1.5;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
user-select: none;
transition: all 0.15s ease-in-out;
}
.ordojs-button-primary {
color: #fff;
background-color: #00d1b2;
border-color: #00d1b2;
}
.ordojs-button-primary:hover {
color: #fff;
background-color: #00c4a7;
border-color: #00c4a7;
}
.ordojs-input {
display: block;
width: 100%;
padding: 0.5em 0.75em;
font-size: 1rem;
line-height: 1.5;
color: #363636;
background-color: #fff;
border: 1px solid #dbdbdb;
border-radius: 4px;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.ordojs-input:focus {
outline: none;
border-color: #3273dc;
box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25);
}`;
return {
css: cssContent,
cssPath: 'styles/bulma.css',
success: true,
metadata: {
framework: 'bulma',
version: '0.9.4'
}
};
}
/**
* Integrate Foundation
*/
async integrateFoundation() {
const cssContent = `/* Foundation CSS */
url('https://cdn.jsdelivr.net/npm/foundation-sites@6.7.5/dist/css/foundation.min.css');
/* OrdoJS Foundation Integration */
.ordojs-component {
position: relative;
}
.ordojs-button {
display: inline-block;
vertical-align: middle;
margin: 0 0 1rem 0;
padding: 0.85em 1em;
border: 1px solid transparent;
border-radius: 0;
transition: background-color 0.25s ease-out, color 0.25s ease-out;
font-family: inherit;
font-size: 0.9rem;
line-height: 1;
text-align: center;
cursor: pointer;
background-color: #1779ba;
color: #fefefe;
}
.ordojs-button:hover {
background-color: #1468a0;
color: #fefefe;
}
.ordojs-input {
display: block;
box-sizing: border-box;
width: 100%;
height: calc(2.4375rem + 2px);
margin: 0 0 1rem 0;
padding: 0.5rem;
border: 1px solid #cacaca;
border-radius: 0;
background-color: #fefefe;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
font-family: inherit;
font-size: 1rem;
font-weight: normal;
line-height: 1.5;
color: #0a0a0a;
transition: box-shadow 0.5s, border-color 0.25s ease-in-out;
}
.ordojs-input:focus {
outline: none;
border: 1px solid #8a8a8a;
background-color: #fefefe;
box-shadow: 0 0 5px #cacaca;
transition: box-shadow 0.5s, border-color 0.25s ease-in-out;
}`;
return {
css: cssContent,
cssPath: 'styles/foundation.css',
success: true,
metadata: {
framework: 'foundation',
version: '6.7.5'
}
};
}
/**
* Integrate custom CSS framework
*/
async integrateCustom() {
if (!this.options.customCSSPath) {
throw new Error('Custom CSS path is required for custom framework integration');
}
try {
const cssContent = await fs.readFile(this.options.customCSSPath, 'utf-8');
return {
css: cssContent,
cssPath: 'styles/custom.css',
success: true,
metadata: {
framework: 'custom',
sourcePath: this.options.customCSSPath
}
};
}
catch (error) {
throw new Error(`Failed to read custom CSS file: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Generate PostCSS configuration
*/
generatePostCSSConfig() {
const config = {
plugins: {}
};
if (this.options.framework === 'tailwind') {
config.plugins.tailwindcss = {};
config.plugins.autoprefixer = {};
if (this.options.purgeUnused) {
config.plugins['@fullhuman/postcss-purgecss'] = {
content: this.options.contentPaths || [],
defaultExtractor: (content) => content.match(/[A-Za-z0-9-_:/]+/g) || [],
safelist: [
'html',
'body',
/^ordojs-/,
/^data-ordojs-/
]
};
}
}
// Add custom PostCSS plugins
if (this.options.postcss?.plugins) {
for (const plugin of this.options.postcss.plugins) {
config.plugins[plugin] = this.options.postcss.options?.[plugin] || {};
}
}
return config;
}
/**
* Generate package.json dependencies for the framework
*/
generateDependencies() {
const dependencies = {};
switch (this.options.framework) {
case 'tailwind':
dependencies['tailwindcss'] = '^3.3.0';
dependencies['@tailwindcss/forms'] = '^0.5.6';
dependencies['@tailwindcss/typography'] = '^0.5.9';
dependencies['@tailwindcss/aspect-ratio'] = '^0.1.1';
dependencies['autoprefixer'] = '^10.4.14';
dependencies['postcss'] = '^8.4.24';
if (this.options.purgeUnused) {
dependencies['@fullhuman/postcss-purgecss'] = '^5.0.0';
}
break;
case 'bootstrap':
dependencies['bootstrap'] = '^5.3.0';
break;
case 'bulma':
dependencies['bulma'] = '^0.9.4';
break;
case 'foundation':
dependencies['foundation-sites'] = '^6.7.5';
break;
}
return dependencies;
}
/**
* Generate framework-specific configuration files
*/
async generateConfigFiles(outputDir) {
const generatedFiles = [];
switch (this.options.framework) {
case 'tailwind':
const tailwindConfig = this.generateTailwindConfig();
const tailwindConfigPath = path.join(outputDir, 'tailwind.config.js');
await fs.writeFile(tailwindConfigPath, `module.exports = ${JSON.stringify(tailwindConfig, null, 2)};`);
generatedFiles.push(tailwindConfigPath);
const postcssConfig = this.generatePostCSSConfig();
const postcssConfigPath = path.join(outputDir, 'postcss.config.js');
await fs.writeFile(postcssConfigPath, `module.exports = ${JSON.stringify(postcssConfig, null, 2)};`);
generatedFiles.push(postcssConfigPath);
break;
}
return generatedFiles;
}
}
//# sourceMappingURL=css-framework-integration.js.map