@marvalt/wparser 0.1.41 → 0.1.43

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.cjs CHANGED
@@ -2136,34 +2136,67 @@ function extractBackgroundColor(block, context) {
2136
2136
  */
2137
2137
  function extractTextColor(block, context) {
2138
2138
  const attrs = block.attributes || {};
2139
- const wpColorName = attrs['textColor'] || attrs['text'];
2139
+ // Try multiple possible attribute names for text color
2140
+ let wpColorName = attrs['textColor'] ||
2141
+ attrs['text'] ||
2142
+ attrs['textColorSlug'] ||
2143
+ null;
2144
+ // If not found in attributes, check className for WordPress color classes
2145
+ // WordPress uses classes like: has-accent-4-color, has-contrast-color
2146
+ // Note: We need to avoid matching has-{color}-background-color, so we check for -color that's not followed by -background
2147
+ if (!wpColorName && attrs['className']) {
2148
+ const className = attrs['className'];
2149
+ // Match: has-{color}-color (text color class, not background-color)
2150
+ // This regex matches "has-accent-4-color" but not "has-accent-4-background-color"
2151
+ const colorMatch = className.match(/has-([\w-]+)-color(?!-background)/);
2152
+ if (colorMatch && colorMatch[1]) {
2153
+ wpColorName = colorMatch[1];
2154
+ }
2155
+ // Enhanced debug logging
2156
+ if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
2157
+ if (!wpColorName) {
2158
+ const hasColorClass = className.includes('-color');
2159
+ if (hasColorClass && context.colorMapper) {
2160
+ console.log('🔍 extractTextColor - Found color class in className but no match:', {
2161
+ blockName: block.name,
2162
+ className: className,
2163
+ colorClasses: className.split(' ').filter(c => c.includes('-color')),
2164
+ allAttrs: Object.keys(attrs),
2165
+ });
2166
+ }
2167
+ }
2168
+ else {
2169
+ console.log('✅ extractTextColor - Found color in className:', wpColorName);
2170
+ }
2171
+ }
2172
+ }
2140
2173
  if (!wpColorName || typeof wpColorName !== 'string') {
2141
2174
  return null;
2142
2175
  }
2143
- // Special handling for common WordPress color names when used as text color
2144
- // These mappings take precedence because text color semantics differ from background color
2145
- const textColorMap = {
2146
- 'contrast': 'text-gray-900', // Contrast text is typically dark/black (opposite of contrast background)
2147
- 'base': 'text-white', // Base text on dark backgrounds
2148
- };
2149
- // Check special text color mappings first
2150
- if (textColorMap[wpColorName]) {
2151
- return textColorMap[wpColorName];
2152
- }
2153
2176
  // Use colorMapper from context if available
2154
- // Note: colorMapper might return combined classes like "bg-gray-900 text-white"
2155
- // We'll extract just the text color part
2177
+ // Note: colorMapper returns combined classes like "bg-[#FBFAF3] text-gray-900"
2178
+ // We need to extract just the text color part
2156
2179
  if (context.colorMapper) {
2157
2180
  const mapped = context.colorMapper(wpColorName);
2158
2181
  if (mapped) {
2159
- // If the mapped class includes text color (e.g., "bg-gray-900 text-white"),
2160
- // extract just the text color part
2161
- const textColorMatch = mapped.match(/\btext-\S+/);
2162
- if (textColorMatch) {
2163
- return textColorMatch[0];
2182
+ // Extract text color classes (e.g., "text-white", "text-gray-900")
2183
+ // Match text- classes but not text- in the middle of other classes
2184
+ const textColorMatch = mapped.match(/\btext-[\w-]+/g);
2185
+ if (textColorMatch && textColorMatch.length > 0) {
2186
+ // Return the last text color class (in case there are multiple)
2187
+ const result = textColorMatch[textColorMatch.length - 1];
2188
+ // Debug logging
2189
+ if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
2190
+ console.log('🎨 extractTextColor - Mapped', wpColorName, '→', result, '(from:', mapped, ')');
2191
+ }
2192
+ return result;
2164
2193
  }
2194
+ // If no text color class found, try to determine from the background color
2195
+ // For theme palette colors, we can infer text color based on brightness
2196
+ // But for now, return null if no text color is in the mapped result
2165
2197
  }
2166
2198
  }
2199
+ // Fallback: return null (no text color applied, will inherit from parent)
2167
2200
  return null;
2168
2201
  }
2169
2202
  /**
@@ -2307,6 +2340,9 @@ const Paragraph = ({ block, context }) => {
2307
2340
  const attrs = block.attributes || {};
2308
2341
  const textAlign = getTextAlignClasses(attrs['align']);
2309
2342
  const spacing = getSpacing(context.spacingConfig || context.registry.spacingConfig, 'paragraph', 'my-6');
2343
+ // Extract text color if specified
2344
+ const textColor = extractTextColor(block, context);
2345
+ const textColorClass = textColor || '';
2310
2346
  // Check if innerHTML contains HTML elements (like links, strong, em, etc.)
2311
2347
  const hasHTML = block.innerHTML && /<[a-z][\s\S]*>/i.test(block.innerHTML);
2312
2348
  // Check if content contains shortcodes (check both HTML and text content)
@@ -2342,17 +2378,17 @@ const Paragraph = ({ block, context }) => {
2342
2378
  const hasBlockLevelContent = React.Children.toArray(parts).some((part) => isBlockLevelElement(part));
2343
2379
  if (hasBlockLevelContent) {
2344
2380
  // Render block-level content without <p> wrapper, but add spacing wrapper
2345
- return jsxRuntimeExports.jsx("div", { className: spacing, children: parts });
2381
+ return jsxRuntimeExports.jsx("div", { className: buildClassName(spacing, textColorClass), children: parts });
2346
2382
  }
2347
2383
  // Render shortcode parts inside paragraph (shortcodes are processed as React components)
2348
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), children: parts });
2384
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), children: parts });
2349
2385
  }
2350
2386
  // If innerHTML contains HTML elements but no shortcodes, render it directly (preserves links, formatting, etc.)
2351
2387
  if (hasHTML && block.innerHTML) {
2352
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), dangerouslySetInnerHTML: { __html: htmlContent } });
2388
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), dangerouslySetInnerHTML: { __html: htmlContent } });
2353
2389
  }
2354
2390
  // No HTML and no shortcodes, just render plain text content
2355
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), children: textContent });
2391
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), children: textContent });
2356
2392
  };
2357
2393
  const Heading = ({ block, children, context }) => {
2358
2394
  const attrs = block.attributes || {};