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