meno-core 1.0.48 → 1.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-static.js +7 -7
- package/dist/chunks/{chunk-UUA5LEWF.js → chunk-6IVUG7FY.js} +138 -7
- package/dist/chunks/chunk-6IVUG7FY.js.map +7 -0
- package/dist/chunks/{chunk-B2RTLDXY.js → chunk-AZQYF6KE.js} +132 -1
- package/dist/chunks/chunk-AZQYF6KE.js.map +7 -0
- package/dist/chunks/{chunk-NKUV77SR.js → chunk-CHD5UCFF.js} +21 -9
- package/dist/chunks/{chunk-NKUV77SR.js.map → chunk-CHD5UCFF.js.map} +2 -2
- package/dist/chunks/{chunk-TPQ7APVQ.js → chunk-EQYDSPBB.js} +418 -62
- package/dist/chunks/chunk-EQYDSPBB.js.map +7 -0
- package/dist/chunks/{chunk-RQSTH2BS.js → chunk-H4JSCDNW.js} +2 -2
- package/dist/chunks/{chunk-EK4KESLU.js → chunk-J23ZX5AP.js} +8 -2
- package/dist/chunks/{chunk-EK4KESLU.js.map → chunk-J23ZX5AP.js.map} +2 -2
- package/dist/chunks/{chunk-D5E3OKSL.js → chunk-JER5NQVM.js} +5 -5
- package/dist/chunks/{chunk-BJRKEPMP.js → chunk-KPU2XHOS.js} +5 -2
- package/dist/chunks/{chunk-BJRKEPMP.js.map → chunk-KPU2XHOS.js.map} +2 -2
- package/dist/chunks/{chunk-NP76N4HQ.js → chunk-LKAGAQ3M.js} +2 -2
- package/dist/chunks/{chunk-3FHJUHAS.js → chunk-S2CX6HFM.js} +260 -25
- package/dist/chunks/chunk-S2CX6HFM.js.map +7 -0
- package/dist/chunks/{configService-IGJEC3MC.js → configService-CCA6AIDI.js} +3 -3
- package/dist/entries/server-router.js +9 -9
- package/dist/entries/server-router.js.map +2 -2
- package/dist/lib/client/index.js +54 -20
- package/dist/lib/client/index.js.map +3 -3
- package/dist/lib/server/index.js +9 -9
- package/dist/lib/shared/index.js +46 -10
- package/dist/lib/shared/index.js.map +3 -3
- package/entries/server-router.tsx +6 -2
- package/lib/client/core/ComponentBuilder.ts +8 -1
- package/lib/client/core/builders/embedBuilder.ts +15 -2
- package/lib/client/core/builders/linkNodeBuilder.ts +15 -2
- package/lib/client/core/builders/localeListBuilder.ts +17 -6
- package/lib/client/styles/StyleInjector.ts +3 -2
- package/lib/client/theme.ts +4 -4
- package/lib/server/cssGenerator.test.ts +64 -1
- package/lib/server/cssGenerator.ts +48 -9
- package/lib/server/providers/fileSystemCMSProvider.test.ts +163 -0
- package/lib/server/providers/fileSystemCMSProvider.ts +200 -11
- package/lib/server/routes/index.ts +1 -1
- package/lib/server/routes/pages.ts +23 -1
- package/lib/server/services/cmsService.test.ts +246 -0
- package/lib/server/services/cmsService.ts +122 -5
- package/lib/server/services/configService.ts +5 -0
- package/lib/server/ssr/attributeBuilder.ts +41 -0
- package/lib/server/ssr/htmlGenerator.test.ts +113 -0
- package/lib/server/ssr/htmlGenerator.ts +51 -4
- package/lib/server/ssr/liveReloadIntegration.test.ts +209 -0
- package/lib/server/ssr/ssrRenderer.test.ts +306 -0
- package/lib/server/ssr/ssrRenderer.ts +182 -44
- package/lib/shared/cssGeneration.test.ts +267 -1
- package/lib/shared/cssGeneration.ts +240 -18
- package/lib/shared/cssProperties.test.ts +247 -1
- package/lib/shared/cssProperties.ts +196 -6
- package/lib/shared/interfaces/contentProvider.ts +39 -6
- package/lib/shared/pathSecurity.ts +16 -0
- package/lib/shared/responsiveScaling.test.ts +143 -0
- package/lib/shared/responsiveScaling.ts +253 -2
- package/lib/shared/themeDefaults.test.ts +3 -3
- package/lib/shared/themeDefaults.ts +3 -3
- package/lib/shared/types/cms.ts +28 -3
- package/lib/shared/types/index.ts +1 -0
- package/lib/shared/utilityClassConfig.ts +3 -0
- package/lib/shared/utilityClassMapper.test.ts +123 -0
- package/lib/shared/utilityClassMapper.ts +179 -8
- package/lib/shared/validation/schemas.ts +15 -1
- package/lib/shared/validation/validators.ts +26 -1
- package/package.json +1 -1
- package/dist/chunks/chunk-3FHJUHAS.js.map +0 -7
- package/dist/chunks/chunk-B2RTLDXY.js.map +0 -7
- package/dist/chunks/chunk-TPQ7APVQ.js.map +0 -7
- package/dist/chunks/chunk-UUA5LEWF.js.map +0 -7
- /package/dist/chunks/{chunk-RQSTH2BS.js.map → chunk-H4JSCDNW.js.map} +0 -0
- /package/dist/chunks/{chunk-D5E3OKSL.js.map → chunk-JER5NQVM.js.map} +0 -0
- /package/dist/chunks/{chunk-NP76N4HQ.js.map → chunk-LKAGAQ3M.js.map} +0 -0
- /package/dist/chunks/{configService-IGJEC3MC.js.map → configService-CCA6AIDI.js.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../lib/shared/breakpoints.ts", "../../lib/shared/i18n.ts", "../../lib/shared/responsiveScaling.ts", "../../lib/shared/pxToRem.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Shared Breakpoint Configuration\n * Defines breakpoints for responsive design\n * Supports dynamic breakpoints from project.config.json\n */\n\n/**\n * Extended breakpoint entry with separate CSS threshold and editor preview width\n * - breakpoint: The CSS media query threshold (max-width value)\n * - previewPoint: The width used in editor preview mode (defaults to breakpoint if not specified)\n * - label: Optional display label for UI (e.g., \"Tablet Landscape\", \"Phone\")\n */\nexport interface BreakpointEntry {\n breakpoint: number;\n previewPoint: number;\n label?: string;\n}\n\n/**\n * Input format for breakpoint config - supports both legacy (number) and new (object) format\n * Legacy: { tablet: 1024 }\n * New: { tablet: { breakpoint: 1024, previewPoint: 768 } }\n */\nexport type BreakpointConfigInput = Record<string, number | BreakpointEntry>;\n\n/**\n * Normalized breakpoint config - always uses object format\n */\nexport type BreakpointConfig = Record<string, BreakpointEntry>;\n\n/**\n * Legacy format for backward compatibility (simple number values)\n */\nexport type LegacyBreakpointConfig = Record<string, number>;\n\n// BreakpointName is now a string to support dynamic breakpoints\nexport type BreakpointName = string;\n\nexport const DEFAULT_BREAKPOINTS: BreakpointConfig = {\n tablet: { breakpoint: 1024, previewPoint: 768 },\n mobile: { breakpoint: 540, previewPoint: 375 },\n} as const;\n\n/**\n * Normalize a breakpoint config input to the full object format\n * Converts legacy number format to object format\n * If previewPoint is not specified, defaults to breakpoint value\n */\nexport function normalizeBreakpointConfig(\n input: BreakpointConfigInput | LegacyBreakpointConfig\n): BreakpointConfig {\n const result: BreakpointConfig = {};\n\n for (const [name, value] of Object.entries(input)) {\n if (typeof value === 'number') {\n // Legacy format: number -> { breakpoint: value, previewPoint: value }\n result[name] = { breakpoint: value, previewPoint: value };\n } else if (typeof value === 'object' && value !== null) {\n // New format: ensure both values exist, preserve label if present\n result[name] = {\n breakpoint: value.breakpoint,\n previewPoint: value.previewPoint ?? value.breakpoint,\n ...(value.label !== undefined && { label: value.label }),\n };\n }\n }\n\n return result;\n}\n\n/**\n * Get just the breakpoint values for CSS generation (media queries)\n * Returns Record<string, number> with breakpoint values\n */\nexport function getBreakpointValues(config: BreakpointConfig): LegacyBreakpointConfig {\n const result: LegacyBreakpointConfig = {};\n for (const [name, entry] of Object.entries(config)) {\n result[name] = entry.breakpoint;\n }\n return result;\n}\n\n/**\n * Get just the preview point values for editor preview\n * Returns Record<string, number> with previewPoint values\n */\nexport function getPreviewPointValues(config: BreakpointConfig): LegacyBreakpointConfig {\n const result: LegacyBreakpointConfig = {};\n for (const [name, entry] of Object.entries(config)) {\n result[name] = entry.previewPoint;\n }\n return result;\n}\n\n/**\n * Get all breakpoint names from the breakpoint configuration\n * Always includes 'base' plus all keys from the config\n * Order: base (desktop) -> breakpoints sorted by value descending (largest to smallest viewport)\n */\nexport function getAllBreakpointNames(\n breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS\n): BreakpointName[] {\n // Base is always included first\n const names: BreakpointName[] = ['base'];\n\n // Get all breakpoint names from config and sort by breakpoint value (descending)\n // This ensures proper order: largest viewport first\n const breakpointEntries = Object.entries(breakpoints);\n breakpointEntries.sort((a, b) => b[1].breakpoint - a[1].breakpoint); // Sort descending by breakpoint value\n\n // Add breakpoint names in sorted order\n for (const [name] of breakpointEntries) {\n names.push(name);\n }\n\n return names;\n}\n\n/**\n * Get active breakpoint name based on viewport width\n * Returns the smallest breakpoint that the viewport width is less than or equal to\n * If viewport is larger than all breakpoints, returns 'base'\n * Uses .breakpoint value for comparison (CSS threshold)\n */\nexport function getBreakpointName(\n viewportWidth: number,\n breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS\n): BreakpointName {\n // Sort breakpoints by breakpoint value (ascending) to find the smallest one that matches\n const breakpointEntries = Object.entries(breakpoints);\n breakpointEntries.sort((a, b) => a[1].breakpoint - b[1].breakpoint); // Sort ascending by breakpoint value\n\n // Find the smallest breakpoint that viewport width is <= to\n for (const [name, entry] of breakpointEntries) {\n if (viewportWidth <= entry.breakpoint) {\n return name;\n }\n }\n\n // If viewport is larger than all breakpoints, return 'base'\n return 'base';\n}\n\n/**\n * Get display label for a breakpoint\n * Priority:\n * 1. Label from config (if set)\n * 2. \"Desktop\" for 'base'\n * 3. Auto-capitalized name (camelCase -> Title Case)\n */\nexport function getBreakpointLabel(\n name: BreakpointName,\n breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS\n): string {\n // Base always returns \"Desktop\"\n if (name === 'base') {\n return 'Desktop';\n }\n\n // Check for custom label in config\n const entry = breakpoints[name];\n if (entry?.label) {\n return entry.label;\n }\n\n // Auto-format: camelCase -> Title Case\n // e.g., \"tabletLandscape\" -> \"Tablet Landscape\"\n return name\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (str) => str.toUpperCase())\n .trim();\n}\n", "/**\n * Internationalization (i18n) utilities\n * Handles inline translation resolution for component props\n */\n\nimport type { I18nValue, I18nConfig, LocaleConfig } from './types/components';\n\n/**\n * Default i18n configuration\n */\nexport const DEFAULT_I18N_CONFIG: I18nConfig = {\n defaultLocale: 'en',\n locales: [\n { code: 'en', name: 'English', nativeName: 'English', langTag: 'en-US' }\n ],\n};\n\n// ============================================\n// Locale helper functions\n// ============================================\n\n/**\n * Get array of locale codes from config\n */\nexport function getLocaleCodes(config: I18nConfig): string[] {\n return config.locales.map(loc => loc.code);\n}\n\n/**\n * Find a locale config by its code\n */\nexport function findLocaleByCode(config: I18nConfig, code: string): LocaleConfig | undefined {\n return config.locales.find(loc => loc.code === code);\n}\n\n/**\n * Check if a locale code is valid/exists in config\n */\nexport function isValidLocaleCode(config: I18nConfig, code: string): boolean {\n return config.locales.some(loc => loc.code === code);\n}\n\n// ============================================\n// Config Migration (old string[] -> new LocaleConfig[])\n// ============================================\n\n/**\n * Convert old locale format (string) to new format (LocaleConfig)\n */\nfunction migrateLocaleString(code: string): LocaleConfig {\n const upperCode = code.toUpperCase();\n return {\n code: code.toLowerCase(),\n name: upperCode,\n nativeName: upperCode,\n langTag: `${code.toLowerCase()}-${upperCode}`,\n };\n}\n\n/**\n * Check if locales array is in old string format\n */\nfunction isOldLocaleFormat(locales: unknown): locales is string[] {\n return Array.isArray(locales) && locales.length > 0 && typeof locales[0] === 'string';\n}\n\n/**\n * Migrate i18n config from old format to new format\n * Old: { defaultLocale: \"en\", locales: [\"en\", \"pl\"] }\n * New: { defaultLocale: \"en\", locales: [{ code: \"en\", name: \"EN\", ... }] }\n */\nexport function migrateI18nConfig(i18n: unknown): I18nConfig {\n if (!i18n || typeof i18n !== 'object') {\n return DEFAULT_I18N_CONFIG;\n }\n\n const config = i18n as Record<string, unknown>;\n const defaultLocale = (config.defaultLocale as string) || 'en';\n const locales = config.locales;\n\n if (!locales || !Array.isArray(locales)) {\n return DEFAULT_I18N_CONFIG;\n }\n\n // Migrate old string[] format\n if (isOldLocaleFormat(locales)) {\n return {\n defaultLocale,\n locales: locales.map(migrateLocaleString),\n };\n }\n\n // Already in new format\n return {\n defaultLocale,\n locales: locales as LocaleConfig[],\n };\n}\n\n/**\n * Type guard to check if a value is an I18nValue object\n */\nexport function isI18nValue(value: unknown): value is I18nValue {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n return '_i18n' in value && (value as Record<string, unknown>)._i18n === true;\n}\n\n/**\n * Resolve a single translation value for the given locale\n * Fallback order: exact locale -> default locale -> first available -> empty\n * Works with any value type (strings, arrays for list props, etc.)\n */\nexport function resolveTranslation(\n value: I18nValue,\n locale: string,\n config: I18nConfig\n): unknown {\n // Try exact locale match (any type - string, array, etc.)\n if (locale in value && value[locale] !== undefined && locale !== '_i18n') {\n return value[locale];\n }\n\n // Try default locale\n if (config.defaultLocale in value && value[config.defaultLocale] !== undefined) {\n return value[config.defaultLocale];\n }\n\n // Get first available value (skip _i18n marker)\n for (const key of Object.keys(value)) {\n if (key !== '_i18n' && value[key] !== undefined) {\n return value[key];\n }\n }\n\n // Return empty string for string i18n, empty array for list i18n\n // Check if any value is an array to determine the type\n const hasArrayValue = Object.entries(value).some(\n ([k, v]) => k !== '_i18n' && Array.isArray(v)\n );\n return hasArrayValue ? [] : '';\n}\n\n/**\n * Resolve a value that might be an I18nValue or a regular value\n * Returns the original value if not an I18nValue\n */\nexport function resolveI18nValue(\n value: unknown,\n locale: string,\n config: I18nConfig\n): unknown {\n if (isI18nValue(value)) {\n return resolveTranslation(value, locale, config);\n }\n return value;\n}\n\n/**\n * Recursively resolve all I18nValue objects in a props object\n */\nexport function resolveI18nInProps(\n props: Record<string, unknown>,\n locale: string,\n config: I18nConfig\n): Record<string, unknown> {\n const resolved: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n if (isI18nValue(value)) {\n resolved[key] = resolveTranslation(value, locale, config);\n } else if (Array.isArray(value)) {\n resolved[key] = value.map((item) =>\n isI18nValue(item) ? resolveTranslation(item, locale, config) : item\n );\n } else if (typeof value === 'object' && value !== null) {\n // Recursively resolve nested objects (but not I18nValue which is already handled)\n resolved[key] = resolveI18nInProps(\n value as Record<string, unknown>,\n locale,\n config\n );\n } else {\n resolved[key] = value;\n }\n }\n\n return resolved;\n}\n\n/**\n * Extract locale from URL path prefix\n * e.g., '/en/about' -> 'en', '/pl/' -> 'pl', '/about' -> null\n */\nexport function extractLocaleFromPath(\n path: string,\n config: I18nConfig\n): { locale: string | null; pathWithoutLocale: string } {\n // Remove leading slash and split\n const cleanPath = path.startsWith('/') ? path.slice(1) : path;\n const segments = cleanPath.split('/');\n\n if (segments.length > 0 && isValidLocaleCode(config, segments[0])) {\n const locale = segments[0];\n const pathWithoutLocale = '/' + segments.slice(1).join('/');\n return { locale, pathWithoutLocale: pathWithoutLocale || '/' };\n }\n\n return { locale: null, pathWithoutLocale: path };\n}\n\n/**\n * Build a localized path\n * e.g., ('/about', 'pl') -> '/pl/about'\n */\nexport function buildLocalizedPath(path: string, locale: string): string {\n const cleanPath = path.startsWith('/') ? path : '/' + path;\n return `/${locale}${cleanPath === '/' ? '' : cleanPath}`;\n}\n\n/**\n * Locale context containing resolved locale info\n */\nexport interface LocaleContext {\n /** The effective locale (never null) */\n locale: string;\n /** Path with locale prefix removed */\n pathWithoutLocale: string;\n /** Whether the current locale is the default */\n isDefaultLocale: boolean;\n}\n\n/**\n * Parse locale from path and return full context with effective locale\n * Combines extractLocaleFromPath + defaultLocale resolution in one call\n */\nexport function parseLocaleFromPath(\n path: string,\n config: I18nConfig\n): LocaleContext {\n const { locale, pathWithoutLocale } = extractLocaleFromPath(path, config);\n const effectiveLocale = locale || config.defaultLocale;\n\n return {\n locale: effectiveLocale,\n pathWithoutLocale,\n isDefaultLocale: effectiveLocale === config.defaultLocale\n };\n}\n\n// ============================================\n// Client-side locale persistence utilities\n// ============================================\n\nconst LOCALE_STORAGE_KEY = 'meno_locale_preference';\nconst OLD_LOCALE_STORAGE_KEY = 'uplo_locale_preference';\n\n/**\n * Migrate locale storage key from old to new (one-time migration)\n */\nfunction migrateLocaleStorageKey(): void {\n if (typeof window === 'undefined') return;\n try {\n const oldValue = localStorage.getItem(OLD_LOCALE_STORAGE_KEY);\n const newValue = localStorage.getItem(LOCALE_STORAGE_KEY);\n if (oldValue && !newValue) {\n localStorage.setItem(LOCALE_STORAGE_KEY, oldValue);\n localStorage.removeItem(OLD_LOCALE_STORAGE_KEY);\n }\n } catch {\n // Storage not available\n }\n}\n\n/**\n * Get stored locale preference from localStorage (client-side only)\n */\nexport function getStoredLocale(): string | null {\n if (typeof window === 'undefined') return null;\n try {\n // Migrate from old key if needed\n migrateLocaleStorageKey();\n return localStorage.getItem(LOCALE_STORAGE_KEY);\n } catch {\n return null;\n }\n}\n\n/**\n * Store locale preference to localStorage (client-side only)\n */\nexport function setStoredLocale(locale: string): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(LOCALE_STORAGE_KEY, locale);\n } catch {\n // Storage not available\n }\n}\n\n/**\n * Clear stored locale preference (client-side only)\n */\nexport function clearStoredLocale(): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.removeItem(LOCALE_STORAGE_KEY);\n } catch {\n // Storage not available\n }\n}\n", "/**\n * Responsive Scaling Calculator\n * Automatically calculates responsive values for different breakpoints\n * using configured scale multipliers\n */\n\n/**\n * Scale configuration for a CSS property category\n * Keys are breakpoint names (e.g., 'tablet', 'mobile', 'small')\n * Values are scale multipliers (e.g., 0.88, 0.75)\n */\nexport type BreakpointScales = Record<string, number>;\n\nexport interface ResponsiveScales {\n enabled: boolean;\n baseReference: number;\n fontSize?: BreakpointScales;\n padding?: BreakpointScales;\n margin?: BreakpointScales;\n gap?: BreakpointScales;\n borderRadius?: BreakpointScales;\n size?: BreakpointScales;\n [key: string]: boolean | number | BreakpointScales | undefined;\n}\n\nexport type CSSPropertyType = 'fontSize' | 'padding' | 'margin' | 'gap' | 'paddingTop' | 'paddingRight' | 'paddingBottom' | 'paddingLeft' | 'marginTop' | 'marginRight' | 'marginBottom' | 'marginLeft' | 'rowGap' | 'columnGap' | 'borderRadius' | 'borderTopLeftRadius' | 'borderTopRightRadius' | 'borderBottomLeftRadius' | 'borderBottomRightRadius' | 'width' | 'height' | 'maxWidth' | 'maxHeight' | 'minWidth' | 'minHeight';\n\n/**\n * Map CSS property to its scale category\n * e.g., paddingTop -> padding, marginRight -> margin\n */\nfunction getScaleCategory(property: CSSPropertyType): keyof ResponsiveScales | null {\n const propertyStr = property as string;\n if (property === 'fontSize') return 'fontSize';\n if (propertyStr.startsWith('padding')) return 'padding';\n if (propertyStr.startsWith('margin')) return 'margin';\n if (property === 'gap' || property === 'rowGap' || property === 'columnGap') return 'gap';\n if (propertyStr === 'borderRadius' || (propertyStr.startsWith('border') && propertyStr.includes('Radius'))) return 'borderRadius';\n if (property === 'width' || property === 'height' || property === 'maxWidth' || property === 'maxHeight' || property === 'minWidth' || property === 'minHeight') return 'size';\n return null;\n}\n\n/**\n * Extract numeric value and unit from a CSS value string\n * e.g., \"67px\" -> { value: 67, unit: \"px\" }\n */\nfunction parseValue(valueStr: string): { value: number; unit: string } | null {\n const match = valueStr.trim().match(/^(-?[\\d.]+)(px|rem|em|%|pt)$/);\n if (!match) return null;\n return {\n value: parseFloat(match[1]),\n unit: match[2],\n };\n}\n\n/**\n * Calculate responsive value using the formula:\n * responsive_value = base_value + (base_value - base_reference) * (scale - 1)\n */\nexport function calculateResponsiveValue(\n baseValue: number,\n baseReference: number,\n scale: number\n): number {\n // Values at or below baseReference stay unchanged\n if (Math.abs(baseValue) <= baseReference) {\n return Math.round(baseValue);\n }\n const scaled = baseValue + (baseValue - baseReference) * (scale - 1);\n return Math.round(scaled);\n}\n\n/**\n * Get the scale multiplier for a specific property and breakpoint\n * @param scales - The responsive scales configuration\n * @param property - The CSS property type (e.g., 'fontSize', 'padding')\n * @param breakpoint - The breakpoint name (e.g., 'tablet', 'mobile', 'small')\n */\nexport function getScaleMultiplier(\n scales: ResponsiveScales,\n property: CSSPropertyType,\n breakpoint: string\n): number | null {\n const category = getScaleCategory(property);\n if (!category || !scales[category]) return null;\n\n const scaleConfig = scales[category] as BreakpointScales | undefined;\n return scaleConfig?.[breakpoint] ?? null;\n}\n\n/**\n * Parse multi-value CSS property (e.g., \"20px 40px\" for padding)\n * Handles both space-separated (\"20px 40px\") and hyphen-separated (\"20px-40px\") formats\n * Returns array of individual values\n */\nexport function parseMultiValue(valueStr: string): string[] {\n // First, convert hyphen separators to spaces (for class names like \"p-0-80px\" \u2192 \"0-80px\")\n // But only convert hyphens between values (digit/px followed by hyphen followed by digit/px)\n const normalized = valueStr.replace(/(?<=\\w)-(?=\\d|auto|inherit|initial|unset)/g, ' ');\n return normalized.trim().split(/\\s+/).filter(v => v.length > 0);\n}\n\n/**\n * Scale a single CSS value using the responsive scale\n * Returns null if the value cannot be parsed (no unit)\n */\nexport function scaleValue(\n valueStr: string,\n baseReference: number,\n scale: number\n): string | null {\n const parsed = parseValue(valueStr);\n if (!parsed) return null;\n\n // `%` and `em` are already relative to their rendering context\n // (container / local font-size), so they should not be rescaled.\n if (parsed.unit === '%' || parsed.unit === 'em') {\n return valueStr.trim();\n }\n\n const scaledValue = calculateResponsiveValue(parsed.value, baseReference, scale);\n return `${scaledValue}${parsed.unit}`;\n}\n\n/**\n * Scale a potentially multi-value CSS property\n * e.g., \"20px 40px\" -> \"18px 36px\" (both values scaled independently)\n * Unitless values (0, auto, inherit) are kept as-is\n */\nexport function scalePropertyValue(\n valueStr: string,\n baseReference: number,\n scale: number\n): string | null {\n const parts = parseMultiValue(valueStr);\n if (parts.length === 0) return null;\n\n const scaledParts = parts.map(part => {\n // Try to scale the value\n const scaled = scaleValue(part, baseReference, scale);\n if (scaled !== null) {\n return scaled;\n }\n // If it can't be scaled, keep it as-is (for unitless values like 0, auto, inherit)\n return part;\n });\n\n return scaledParts.join(' ');\n}\n\n/**\n * Get responsive values for all breakpoints\n * Returns object with calculated values for each breakpoint\n *\n * @param baseValue - The base CSS value (e.g., '67px')\n * @param property - The CSS property type (e.g., 'fontSize')\n * @param scales - The responsive scales configuration\n * @param breakpointNames - Optional array of breakpoint names to calculate values for.\n * If not provided, defaults to ['tablet', 'mobile'] for backward compatibility.\n */\nexport function getResponsiveValues(\n baseValue: string,\n property: CSSPropertyType,\n scales: ResponsiveScales,\n breakpointNames?: string[]\n): Record<string, string | null> {\n if (!scales.enabled) {\n return { base: baseValue };\n }\n\n const result: Record<string, string | null> = {\n base: baseValue,\n };\n\n const baseRef = scales.baseReference || 16;\n\n // Use provided breakpoint names or default to tablet/mobile for backward compatibility\n const breakpoints = breakpointNames ?? ['tablet', 'mobile'];\n\n // Calculate value for each breakpoint\n for (const breakpointName of breakpoints) {\n const scale = getScaleMultiplier(scales, property, breakpointName);\n if (scale !== null) {\n result[breakpointName] = scalePropertyValue(baseValue, baseRef, scale);\n }\n }\n\n return result;\n}\n\n/**\n * Resolve the effective value of a CSS variable at a given breakpoint.\n *\n * Precedence (mirrors generateVariablesCSS in cssGenerator.ts so the editor\n * widget stays in sync with what the browser will render):\n * 1. `breakpoint === 'base'` \u2192 variable.value\n * 2. explicit per-variable override \u2192 variable.scales[breakpoint]\n * 3. globally-scaled value (ResponsiveScales multiplier for variable.type)\n * 4. fallback \u2192 variable.value\n */\nexport function resolveVariableValueAtBreakpoint(\n variable: { value: string; type: string; scales?: Record<string, string> },\n breakpoint: string,\n responsiveScales?: ResponsiveScales | null\n): string {\n if (breakpoint === 'base') return variable.value;\n\n const override = variable.scales?.[breakpoint];\n if (override !== undefined) return override;\n\n if (responsiveScales?.enabled && variable.type !== 'none') {\n const scale = getScaleMultiplier(\n responsiveScales,\n variable.type as CSSPropertyType,\n breakpoint\n );\n if (scale !== null) {\n const baseRef = responsiveScales.baseReference || 16;\n const scaled = scalePropertyValue(variable.value, baseRef, scale);\n if (scaled !== null) return scaled;\n }\n }\n\n return variable.value;\n}\n\n/**\n * Default responsive scales configuration\n */\nexport const DEFAULT_RESPONSIVE_SCALES: ResponsiveScales = {\n enabled: false,\n baseReference: 16,\n fontSize: {\n tablet: 0.88,\n mobile: 0.75,\n },\n padding: {\n tablet: 0.75,\n mobile: 0.5,\n },\n margin: {\n tablet: 0.7,\n mobile: 0.45,\n },\n gap: {\n tablet: 0.65,\n mobile: 0.4,\n },\n borderRadius: {\n tablet: 0.85,\n mobile: 0.7,\n },\n size: {\n tablet: 0.9,\n mobile: 0.75,\n },\n};\n", "export interface RemConversionConfig {\n enabled: boolean;\n baseFontSize: number;\n}\n\nexport const DEFAULT_REM_CONFIG: RemConversionConfig = {\n enabled: false,\n baseFontSize: 16,\n};\n\nconst PX_REGEX = /(-?\\d*\\.?\\d+)px/g;\n\n/**\n * Convert all px values in a CSS value string to rem.\n * Handles multi-value shorthands like \"16px 32px\" -> \"1rem 2rem\".\n * 0px becomes \"0\" (unitless).\n */\nexport function convertPxToRem(cssValue: string, baseFontSize: number): string {\n return cssValue.replace(PX_REGEX, (_, num) => {\n const px = parseFloat(num);\n if (px === 0) return '0';\n const rem = px / baseFontSize;\n // Round to 4 decimal places, strip trailing zeros\n const rounded = parseFloat(rem.toFixed(4));\n return `${rounded}rem`;\n });\n}\n\n/**\n * CSS properties that should keep px values (thin borders, shadows).\n */\nconst PX_KEEP_PROPERTIES = new Set([\n 'border-width',\n 'border-top-width',\n 'border-right-width',\n 'border-bottom-width',\n 'border-left-width',\n 'outline-width',\n 'outline-offset',\n 'border',\n 'box-shadow',\n 'text-shadow',\n]);\n\nexport function shouldConvertProperty(cssProperty: string): boolean {\n return !PX_KEEP_PROPERTIES.has(cssProperty);\n}\n\n/**\n * Apply rem conversion to a CSS declarations string (e.g. \"padding: 16px; font-size: 18px\").\n * Checks each property against the exclusion list before converting.\n */\nexport function applyRemConversion(\n declarations: string,\n remConfig?: RemConversionConfig\n): string {\n if (!remConfig?.enabled) return declarations;\n\n return declarations\n .split(';')\n .map(decl => {\n const trimmed = decl.trim();\n if (!trimmed) return '';\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) return trimmed;\n\n const property = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n\n if (shouldConvertProperty(property)) {\n return `${property}: ${convertPxToRem(value, remConfig.baseFontSize)}`;\n }\n return trimmed;\n })\n .filter(Boolean)\n .join('; ');\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|