@marvalt/wparser 0.1.57 → 0.1.59

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
@@ -1874,11 +1874,31 @@ function extractTextAlign(block) {
1874
1874
  }
1875
1875
  /**
1876
1876
  * Extract font size from block
1877
+ * Checks both fontSize attribute and style.typography.fontSize
1877
1878
  */
1878
- function extractFontSize(block) {
1879
+ function extractFontSize(block, context) {
1879
1880
  const attrs = block.attributes || {};
1881
+ // Check inherited font size from context (from parent group)
1882
+ if (context && context.inheritedFontSize) {
1883
+ return context.inheritedFontSize;
1884
+ }
1885
+ // Check style.typography.fontSize (can be a preset name or CSS value)
1886
+ const styleFontSize = attrs['style']?.typography?.fontSize;
1887
+ if (styleFontSize) {
1888
+ if (typeof styleFontSize === 'string') {
1889
+ return styleFontSize;
1890
+ }
1891
+ // If it's an object, it might have a value property
1892
+ if (typeof styleFontSize === 'object' && styleFontSize.value) {
1893
+ return styleFontSize.value;
1894
+ }
1895
+ }
1896
+ // Check fontSize attribute (preset name like 'small', 'medium', etc.)
1880
1897
  const fontSize = attrs['fontSize'];
1881
- return typeof fontSize === 'string' ? fontSize : null;
1898
+ if (typeof fontSize === 'string') {
1899
+ return fontSize;
1900
+ }
1901
+ return null;
1882
1902
  }
1883
1903
  /**
1884
1904
  * Convert image URL to Cloudflare variant if it's a Cloudflare URL
@@ -2156,17 +2176,46 @@ function extractGradientBackground(block) {
2156
2176
  /**
2157
2177
  * Extract and map text color from block attributes
2158
2178
  * Uses colorMapper from context to convert WordPress theme colors to app CSS classes
2179
+ * Also checks style.color.text and inherited colors from parent groups
2159
2180
  *
2160
2181
  * @param block - WordPress block to extract text color from
2161
- * @param context - Render context containing optional colorMapper
2182
+ * @param context - Render context containing optional colorMapper and themePalette
2162
2183
  * @returns CSS class string (e.g., 'text-white') or null if no mapping
2163
2184
  */
2164
2185
  function extractTextColor(block, context) {
2165
2186
  const attrs = block.attributes || {};
2166
- const wpColorName = attrs['textColor'] || attrs['text'];
2187
+ // Check inherited text color from context (from parent group)
2188
+ if (context.inheritedTextColor) {
2189
+ return context.inheritedTextColor;
2190
+ }
2191
+ // Check style.color.text (can be a color name or CSS variable)
2192
+ const styleTextColor = attrs['style']?.color?.text;
2193
+ let wpColorName = null;
2194
+ if (styleTextColor) {
2195
+ if (typeof styleTextColor === 'string') {
2196
+ wpColorName = styleTextColor;
2197
+ }
2198
+ else if (typeof styleTextColor === 'object' && styleTextColor.color) {
2199
+ wpColorName = styleTextColor.color;
2200
+ }
2201
+ }
2202
+ // Fall back to textColor or text attribute
2203
+ if (!wpColorName) {
2204
+ wpColorName = attrs['textColor'] || attrs['text'];
2205
+ }
2167
2206
  if (!wpColorName || typeof wpColorName !== 'string') {
2168
2207
  return null;
2169
2208
  }
2209
+ // If it's a CSS variable or hex color, return it directly
2210
+ if (wpColorName.startsWith('var(') || wpColorName.startsWith('#')) {
2211
+ return `text-[${wpColorName}]`;
2212
+ }
2213
+ // Get theme palette from context if available
2214
+ const themePalette = context?.themePalette || context.registry?.themePalette || context.registry?.wpStyles?.theme_palette;
2215
+ if (themePalette && themePalette[wpColorName]) {
2216
+ // Return inline style class with actual color value
2217
+ return `text-[${themePalette[wpColorName]}]`;
2218
+ }
2170
2219
  // Special handling for common WordPress color names when used as text color
2171
2220
  // These mappings take precedence because text color semantics differ from background color
2172
2221
  const textColorMap = {
@@ -2341,6 +2390,9 @@ const Paragraph = ({ block, context }) => {
2341
2390
  // Extract text color if specified, otherwise inherit from parent (CSS variables handle default)
2342
2391
  const textColor = extractTextColor(block, context);
2343
2392
  const textColorClass = textColor || ''; // Don't hardcode - let CSS variables handle default
2393
+ // Extract font size if specified
2394
+ const fontSize = extractFontSize(block, context);
2395
+ const fontSizeClass = fontSize ? getFontSizeClasses(fontSize) : '';
2344
2396
  // Check if innerHTML contains HTML elements (like links, strong, em, etc.)
2345
2397
  const hasHTML = block.innerHTML && /<[a-z][\s\S]*>/i.test(block.innerHTML);
2346
2398
  // Check if content contains shortcodes (check both HTML and text content)
@@ -2376,24 +2428,44 @@ const Paragraph = ({ block, context }) => {
2376
2428
  const hasBlockLevelContent = React.Children.toArray(parts).some((part) => isBlockLevelElement(part));
2377
2429
  if (hasBlockLevelContent) {
2378
2430
  // Render block-level content without <p> wrapper, but add spacing wrapper
2379
- return jsxRuntimeExports.jsx("div", { className: buildClassName(spacing, textColorClass), children: parts });
2431
+ const fontSize = extractFontSize(block, context);
2432
+ const fontSizeClass = fontSize ? getFontSizeClasses(fontSize) : '';
2433
+ return jsxRuntimeExports.jsx("div", { className: buildClassName(spacing, textColorClass, fontSizeClass), children: parts });
2380
2434
  }
2381
2435
  // Render shortcode parts inside paragraph (shortcodes are processed as React components)
2382
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), children: parts });
2436
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass, fontSizeClass), children: parts });
2383
2437
  }
2384
2438
  // If innerHTML contains HTML elements but no shortcodes, render it directly (preserves links, formatting, etc.)
2385
2439
  if (hasHTML && block.innerHTML) {
2386
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), dangerouslySetInnerHTML: { __html: htmlContent } });
2440
+ // Check if innerHTML already contains a paragraph tag - if so, extract content to avoid double nesting
2441
+ const trimmedContent = htmlContent.trim();
2442
+ if (trimmedContent.startsWith('<p') && trimmedContent.endsWith('</p>')) {
2443
+ // Extract content from paragraph tag
2444
+ const contentMatch = trimmedContent.match(/<p[^>]*>(.*?)<\/p>/s);
2445
+ if (contentMatch) {
2446
+ const innerContent = contentMatch[1];
2447
+ // Check if inner content also has a paragraph (double nesting)
2448
+ if (innerContent.trim().startsWith('<p')) {
2449
+ // Render as div to avoid invalid HTML
2450
+ return jsxRuntimeExports.jsx("div", { className: buildClassName(spacing, textAlign, textColorClass, fontSizeClass), dangerouslySetInnerHTML: { __html: innerContent } });
2451
+ }
2452
+ // Render the extracted content in a paragraph
2453
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass, fontSizeClass), dangerouslySetInnerHTML: { __html: innerContent } });
2454
+ }
2455
+ }
2456
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass, fontSizeClass), dangerouslySetInnerHTML: { __html: htmlContent } });
2387
2457
  }
2388
2458
  // No HTML and no shortcodes, just render plain text content
2389
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), children: textContent });
2459
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass, fontSizeClass), children: textContent });
2390
2460
  };
2391
2461
  const Heading = ({ block, children, context }) => {
2392
2462
  const attrs = block.attributes || {};
2393
2463
  const { level = 2 } = attrs;
2394
2464
  const content = getBlockTextContent(block);
2395
2465
  const textAlign = getTextAlignClasses(attrs['textAlign']);
2396
- const fontSize = getFontSizeClasses(attrs['fontSize']);
2466
+ // Extract font size - check both fontSize attribute and style.typography.fontSize
2467
+ const extractedFontSize = extractFontSize(block, context);
2468
+ const fontSize = extractedFontSize ? getFontSizeClasses(extractedFontSize) : '';
2397
2469
  const Tag = `h${Math.min(Math.max(Number(level) || 2, 1), 6)}`;
2398
2470
  // Use CSS variables for font sizes (defined in index.css) instead of Tailwind classes
2399
2471
  // Only use Tailwind class if explicitly set via fontSize attribute