UNPKG

@ordojs/core

Version:

Core compiler and runtime for OrdoJS framework

500 lines (469 loc) 13.9 kB
/** * @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 `@tailwind base; @tailwind components; @tailwind utilities; /* OrdoJS Tailwind Integration */ @layer base { /* Custom base styles */ html { scroll-behavior: smooth; } body { @apply antialiased; } } @layer components { /* OrdoJS component styles */ .ordojs-component { @apply relative; } .ordojs-button { @apply px-4 py-2 rounded-md font-medium transition-colors duration-200; } .ordojs-button-primary { @apply bg-primary-600 text-white hover:bg-primary-700 focus:ring-2 focus:ring-primary-500 focus:ring-offset-2; } .ordojs-button-secondary { @apply bg-gray-200 text-gray-900 hover:bg-gray-300 focus:ring-2 focus:ring-gray-500 focus:ring-offset-2; } .ordojs-input { @apply block w-full rounded-md border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm; } .ordojs-card { @apply bg-white overflow-hidden shadow rounded-lg; } .ordojs-card-header { @apply px-4 py-5 sm:px-6 border-b border-gray-200; } .ordojs-card-body { @apply px-4 py-5 sm:p-6; } .ordojs-card-footer { @apply px-4 py-4 sm:px-6 border-t border-gray-200; } } @layer utilities { /* OrdoJS utility classes */ .ordojs-text-gradient { @apply bg-gradient-to-r from-primary-600 to-purple-600 bg-clip-text text-transparent; } .ordojs-bg-gradient { @apply bg-gradient-to-r from-primary-600 to-purple-600; } .ordojs-shadow-glow { @apply shadow-lg shadow-primary-500/25; } }`; } /** * Integrate Bootstrap */ async integrateBootstrap() { const cssContent = `/* Bootstrap CSS */ @import 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 */ @import 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 */ @import 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