@marvalt/wparser 0.1.42 → 0.1.45

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/index.d.ts CHANGED
@@ -493,6 +493,11 @@ declare function extractBackgroundColor(block: WordPressBlock, context: RenderCo
493
493
  * @returns CSS class string (e.g., 'text-white') or null if no mapping
494
494
  */
495
495
  declare function extractTextColor(block: WordPressBlock, context: RenderContext): string | null;
496
+ /**
497
+ * Infer a readable text color class based on a background class string.
498
+ * Supports bg-[#hex] and bg-[rgb(...)].
499
+ */
500
+ declare function inferTextColorFromBackground(backgroundClass: string | null): string | null;
496
501
  /**
497
502
  * Extract spacer height from block attributes or innerHTML
498
503
  * Returns height in pixels, or null if not found
@@ -550,5 +555,5 @@ interface SectionWrapperProps {
550
555
  */
551
556
  declare const SectionWrapper: React$1.FC<SectionWrapperProps>;
552
557
 
553
- export { SectionWrapper, WPContent, WPErrorBoundary, WPPage, buildClassName, convertImageToCloudflareVariant, convertImageUrl, convertImageUrls, createDefaultRegistry, createEnhancedRegistry, extractAlignment, extractBackgroundColor, extractBackgroundImage, extractButtonsFromInnerBlocks, extractContent, extractDimRatio, extractFontSize, extractHeadingLevel, extractImageAttributes, extractImageUrl, extractImageUrlWithFallback, extractMediaPosition, extractMinHeight, extractOverlayColor, extractSpacerHeight, extractSubtitleFromInnerBlocks, extractTextAlign, extractTextAlignFromInnerBlocks, extractTextColor, extractTextFromHTML, extractTitle, extractTitleFromInnerBlocks, extractVerticalAlignment, extractVideoIframeFromInnerBlocks, findMatchingMapping, findShortcodes, getAlignmentClasses, getBlockTextContent, getCloudflareVariantUrl, getContainerClasses, getContentSpacingClasses, getFontSizeClasses, getImageAttributes, getImageUrl, getSectionSpacingClasses, getTextAlignClasses, isCloudflareImageUrl, isValidCloudflareUrl, matchesPattern, parseContentPosition, parseGutenbergBlocks, parseShortcodeAttrs, renderNodes, renderTextWithShortcodes };
558
+ export { SectionWrapper, WPContent, WPErrorBoundary, WPPage, buildClassName, convertImageToCloudflareVariant, convertImageUrl, convertImageUrls, createDefaultRegistry, createEnhancedRegistry, extractAlignment, extractBackgroundColor, extractBackgroundImage, extractButtonsFromInnerBlocks, extractContent, extractDimRatio, extractFontSize, extractHeadingLevel, extractImageAttributes, extractImageUrl, extractImageUrlWithFallback, extractMediaPosition, extractMinHeight, extractOverlayColor, extractSpacerHeight, extractSubtitleFromInnerBlocks, extractTextAlign, extractTextAlignFromInnerBlocks, extractTextColor, extractTextFromHTML, extractTitle, extractTitleFromInnerBlocks, extractVerticalAlignment, extractVideoIframeFromInnerBlocks, findMatchingMapping, findShortcodes, getAlignmentClasses, getBlockTextContent, getCloudflareVariantUrl, getContainerClasses, getContentSpacingClasses, getFontSizeClasses, getImageAttributes, getImageUrl, getSectionSpacingClasses, getTextAlignClasses, inferTextColorFromBackground, isCloudflareImageUrl, isValidCloudflareUrl, matchesPattern, parseContentPosition, parseGutenbergBlocks, parseShortcodeAttrs, renderNodes, renderTextWithShortcodes };
554
559
  export type { AuthMode, BlockPattern, BlockRenderer, BlockRendererProps, CloudflareVariantOptions, ColorMapper, ComponentMapping, ComponentRegistry, EnhancedRegistry, ImageConversionOptions, ParseOptions, ParsedShortcode, RenderContext, RenderOptions, SectionWrapperProps, ShortcodeAttributes, ShortcodeRenderer, SpacingConfig, WPContentProps, WPNode, WPPageProps, WordPressBlock, WordPressEmbedded, WordPressFeaturedMedia, WordPressPageMinimal, WordPressTitleField };
package/dist/index.esm.js CHANGED
@@ -2134,6 +2134,7 @@ function extractBackgroundColor(block, context) {
2134
2134
  */
2135
2135
  function extractTextColor(block, context) {
2136
2136
  const attrs = block.attributes || {};
2137
+ const mapper = context.colorMapper;
2137
2138
  // Try multiple possible attribute names for text color
2138
2139
  let wpColorName = attrs['textColor'] ||
2139
2140
  attrs['text'] ||
@@ -2150,31 +2151,42 @@ function extractTextColor(block, context) {
2150
2151
  if (colorMatch && colorMatch[1]) {
2151
2152
  wpColorName = colorMatch[1];
2152
2153
  }
2153
- // Debug logging
2154
- if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development' && !wpColorName) {
2155
- // Check if there are any color-related classes
2156
- const hasColorClass = className.includes('-color');
2157
- if (hasColorClass && context.colorMapper) {
2158
- console.log('🔍 extractTextColor - Found color class in className but no match:', {
2159
- blockName: block.name,
2160
- className: className,
2161
- colorClasses: className.split(' ').filter(c => c.includes('-color')),
2162
- });
2154
+ // Enhanced debug logging
2155
+ if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
2156
+ if (!wpColorName) {
2157
+ const hasColorClass = className.includes('-color');
2158
+ if (hasColorClass && context.colorMapper) {
2159
+ console.log('🔍 extractTextColor - Found color class in className but no match:', {
2160
+ blockName: block.name,
2161
+ className: className,
2162
+ colorClasses: className.split(' ').filter(c => c.includes('-color')),
2163
+ allAttrs: Object.keys(attrs),
2164
+ });
2165
+ }
2166
+ }
2167
+ else {
2168
+ console.log('✅ extractTextColor - Found color in className:', wpColorName);
2163
2169
  }
2164
2170
  }
2165
2171
  }
2166
2172
  if (!wpColorName || typeof wpColorName !== 'string') {
2167
- return null;
2173
+ wpColorName = null;
2168
2174
  }
2169
2175
  // Use colorMapper from context if available
2170
2176
  // Note: colorMapper returns combined classes like "bg-[#FBFAF3] text-gray-900"
2171
2177
  // We need to extract just the text color part
2172
- if (context.colorMapper) {
2173
- const mapped = context.colorMapper(wpColorName);
2178
+ if (mapper && wpColorName) {
2179
+ const mapped = mapper(wpColorName);
2174
2180
  if (mapped) {
2175
- // Extract text color classes (e.g., "text-white", "text-gray-900")
2176
- // Match text- classes but not text- in the middle of other classes
2177
- const textColorMatch = mapped.match(/\btext-[\w-]+/g);
2181
+ // If the mapper provided a background arbitrary value, derive a text color class directly from it
2182
+ const bgArbitrary = mapped.match(/\bbg-\[([^\]]+)\]/);
2183
+ if (bgArbitrary && bgArbitrary[1]) {
2184
+ const derivedText = `text-[${bgArbitrary[1]}]`;
2185
+ return derivedText;
2186
+ }
2187
+ // Extract text color classes (e.g., "text-white", "text-gray-900", "text-[#123456]")
2188
+ // Match text- classes including arbitrary values in brackets
2189
+ const textColorMatch = mapped.match(/\btext-(\[[^\]]+\]|[\w-]+)/g);
2178
2190
  if (textColorMatch && textColorMatch.length > 0) {
2179
2191
  // Return the last text color class (in case there are multiple)
2180
2192
  const result = textColorMatch[textColorMatch.length - 1];
@@ -2192,6 +2204,34 @@ function extractTextColor(block, context) {
2192
2204
  // Fallback: return null (no text color applied, will inherit from parent)
2193
2205
  return null;
2194
2206
  }
2207
+ /**
2208
+ * Infer a readable text color class based on a background class string.
2209
+ * Supports bg-[#hex] and bg-[rgb(...)].
2210
+ */
2211
+ function inferTextColorFromBackground(backgroundClass) {
2212
+ if (!backgroundClass)
2213
+ return null;
2214
+ // Try to extract hex color from arbitrary value class bg-[#xxxxxx]
2215
+ const hexMatch = backgroundClass.match(/bg-\[#?([0-9a-fA-F]{6})\]/);
2216
+ if (hexMatch) {
2217
+ const hex = hexMatch[1];
2218
+ const r = parseInt(hex.slice(0, 2), 16);
2219
+ const g = parseInt(hex.slice(2, 4), 16);
2220
+ const b = parseInt(hex.slice(4, 6), 16);
2221
+ const brightness = (r * 299 + g * 587 + b * 114) / 1000;
2222
+ return brightness < 140 ? 'text-white' : 'text-gray-900';
2223
+ }
2224
+ // Try rgb() form
2225
+ const rgbMatch = backgroundClass.match(/bg-\[rgb\((\d+),\s*(\d+),\s*(\d+)\)\]/i);
2226
+ if (rgbMatch) {
2227
+ const r = parseInt(rgbMatch[1], 10);
2228
+ const g = parseInt(rgbMatch[2], 10);
2229
+ const b = parseInt(rgbMatch[3], 10);
2230
+ const brightness = (r * 299 + g * 587 + b * 114) / 1000;
2231
+ return brightness < 140 ? 'text-white' : 'text-gray-900';
2232
+ }
2233
+ return null;
2234
+ }
2195
2235
  /**
2196
2236
  * Extract spacer height from block attributes or innerHTML
2197
2237
  * Returns height in pixels, or null if not found
@@ -2333,6 +2373,9 @@ const Paragraph = ({ block, context }) => {
2333
2373
  const attrs = block.attributes || {};
2334
2374
  const textAlign = getTextAlignClasses(attrs['align']);
2335
2375
  const spacing = getSpacing(context.spacingConfig || context.registry.spacingConfig, 'paragraph', 'my-6');
2376
+ // Extract text color if specified
2377
+ const textColor = extractTextColor(block, context);
2378
+ const textColorClass = textColor || '';
2336
2379
  // Check if innerHTML contains HTML elements (like links, strong, em, etc.)
2337
2380
  const hasHTML = block.innerHTML && /<[a-z][\s\S]*>/i.test(block.innerHTML);
2338
2381
  // Check if content contains shortcodes (check both HTML and text content)
@@ -2368,17 +2411,17 @@ const Paragraph = ({ block, context }) => {
2368
2411
  const hasBlockLevelContent = React.Children.toArray(parts).some((part) => isBlockLevelElement(part));
2369
2412
  if (hasBlockLevelContent) {
2370
2413
  // Render block-level content without <p> wrapper, but add spacing wrapper
2371
- return jsxRuntimeExports.jsx("div", { className: spacing, children: parts });
2414
+ return jsxRuntimeExports.jsx("div", { className: buildClassName(spacing, textColorClass), children: parts });
2372
2415
  }
2373
2416
  // Render shortcode parts inside paragraph (shortcodes are processed as React components)
2374
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), children: parts });
2417
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), children: parts });
2375
2418
  }
2376
2419
  // If innerHTML contains HTML elements but no shortcodes, render it directly (preserves links, formatting, etc.)
2377
2420
  if (hasHTML && block.innerHTML) {
2378
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), dangerouslySetInnerHTML: { __html: htmlContent } });
2421
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), dangerouslySetInnerHTML: { __html: htmlContent } });
2379
2422
  }
2380
2423
  // No HTML and no shortcodes, just render plain text content
2381
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), children: textContent });
2424
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), children: textContent });
2382
2425
  };
2383
2426
  const Heading = ({ block, children, context }) => {
2384
2427
  const attrs = block.attributes || {};
@@ -2487,6 +2530,8 @@ const Group = ({ block, children, context }) => {
2487
2530
  const layout = attrs['layout'];
2488
2531
  // Extract background color using color mapper
2489
2532
  const backgroundColor = extractBackgroundColor(block, context);
2533
+ // Extract text color (apply on the wrapper so children inherit)
2534
+ const textColor = extractTextColor(block, context) || inferTextColorFromBackground(backgroundColor);
2490
2535
  // Determine if this is a section-level group (has alignment) or content-level
2491
2536
  const isSection = align === 'full' || align === 'wide';
2492
2537
  const containerClass = getContainerClasses(align, layout);
@@ -2500,8 +2545,8 @@ const Group = ({ block, children, context }) => {
2500
2545
  ? 'container'
2501
2546
  : containerClass;
2502
2547
  // Build className with background color if present
2503
- const className = buildClassName(finalContainerClass, spacingClass, backgroundColor // This will be null if no mapping, which is fine
2504
- );
2548
+ const className = buildClassName(finalContainerClass, spacingClass, backgroundColor, // This will be null if no mapping, which is fine
2549
+ textColor);
2505
2550
  return (jsxRuntimeExports.jsx("div", { className: className, children: children }));
2506
2551
  };
2507
2552
  const Columns = ({ block, children }) => {
@@ -2515,9 +2560,10 @@ const Column = ({ block, children, context }) => {
2515
2560
  const width = attrs['width'];
2516
2561
  // Extract background color using color mapper
2517
2562
  const backgroundColor = extractBackgroundColor(block, context);
2563
+ const textColor = extractTextColor(block, context) || inferTextColorFromBackground(backgroundColor);
2518
2564
  // Handle column width (e.g., "50%" becomes flex-basis)
2519
2565
  const style = width ? { flexBasis: width } : undefined;
2520
- return (jsxRuntimeExports.jsx("div", { className: buildClassName('space-y-4 p-6 rounded-lg', backgroundColor), style: style, children: children }));
2566
+ return (jsxRuntimeExports.jsx("div", { className: buildClassName('space-y-4 p-6 rounded-lg', backgroundColor, textColor), style: style, children: children }));
2521
2567
  };
2522
2568
  const Separator = () => jsxRuntimeExports.jsx("hr", { className: "border-gray-200 my-8" });
2523
2569
  const ButtonBlock = ({ block, context }) => {
@@ -3031,5 +3077,5 @@ const SectionWrapper = ({ children, background = 'light', spacing = 'medium', co
3031
3077
  return (jsxRuntimeExports.jsx("section", { className: buildClassName(backgroundClasses[finalBackground] || backgroundClasses.light, spacingClasses[finalSpacing] || spacingClasses.medium, containerClasses[finalContainer] || containerClasses.contained, className), children: children }));
3032
3078
  };
3033
3079
 
3034
- export { SectionWrapper, WPContent, WPErrorBoundary, WPPage, buildClassName, convertImageToCloudflareVariant, convertImageUrl, convertImageUrls, createDefaultRegistry, createEnhancedRegistry, extractAlignment, extractBackgroundColor, extractBackgroundImage, extractButtonsFromInnerBlocks, extractContent, extractDimRatio, extractFontSize, extractHeadingLevel, extractImageAttributes, extractImageUrl, extractImageUrlWithFallback, extractMediaPosition, extractMinHeight, extractOverlayColor, extractSpacerHeight, extractSubtitleFromInnerBlocks, extractTextAlign, extractTextAlignFromInnerBlocks, extractTextColor, extractTextFromHTML, extractTitle, extractTitleFromInnerBlocks, extractVerticalAlignment, extractVideoIframeFromInnerBlocks, findMatchingMapping, findShortcodes, getAlignmentClasses, getBlockTextContent, getCloudflareVariantUrl, getContainerClasses, getContentSpacingClasses, getFontSizeClasses, getImageAttributes, getImageUrl, getSectionSpacingClasses, getTextAlignClasses, isCloudflareImageUrl, isValidCloudflareUrl, matchesPattern, parseContentPosition, parseGutenbergBlocks, parseShortcodeAttrs, renderNodes, renderTextWithShortcodes };
3080
+ export { SectionWrapper, WPContent, WPErrorBoundary, WPPage, buildClassName, convertImageToCloudflareVariant, convertImageUrl, convertImageUrls, createDefaultRegistry, createEnhancedRegistry, extractAlignment, extractBackgroundColor, extractBackgroundImage, extractButtonsFromInnerBlocks, extractContent, extractDimRatio, extractFontSize, extractHeadingLevel, extractImageAttributes, extractImageUrl, extractImageUrlWithFallback, extractMediaPosition, extractMinHeight, extractOverlayColor, extractSpacerHeight, extractSubtitleFromInnerBlocks, extractTextAlign, extractTextAlignFromInnerBlocks, extractTextColor, extractTextFromHTML, extractTitle, extractTitleFromInnerBlocks, extractVerticalAlignment, extractVideoIframeFromInnerBlocks, findMatchingMapping, findShortcodes, getAlignmentClasses, getBlockTextContent, getCloudflareVariantUrl, getContainerClasses, getContentSpacingClasses, getFontSizeClasses, getImageAttributes, getImageUrl, getSectionSpacingClasses, getTextAlignClasses, inferTextColorFromBackground, isCloudflareImageUrl, isValidCloudflareUrl, matchesPattern, parseContentPosition, parseGutenbergBlocks, parseShortcodeAttrs, renderNodes, renderTextWithShortcodes };
3035
3081
  //# sourceMappingURL=index.esm.js.map