Convert to HTML 
          Format JSX 
          Clear All 
        
        
        
       
      
     
    
      
        Kloudbean Zero-Ops Managed Cloud Infrastructure and Hosting    Powerful & Cost-Effective Managed Cloud Hosting
for Everyone
        Start Free Trial 
       
     
    
    
    How to Use the JSX to HTML Converter 
    Simply paste your JSX code  into the input field and click "Convert to HTML" to transform it into standard HTML format. Use the "Format JSX" button to make your JSX more readable first if needed.
    Why This Matters to Developers 
    Converting JSX to HTML is essential for React developers who need to understand how their components will render as plain HTML. This tool makes it easy to visualize the output HTML from your React components.
    Use Cases in Development Workflows 
    This tool is perfect for:
    
      Understanding how React transforms your JSX into HTML elements. 
      Debugging rendering issues by comparing JSX input to HTML output. 
      Creating HTML mockups from existing React components for non-React projects. 
      Teaching and learning how JSX syntax maps to HTML structure. 
     
    Connection to Cloud Hosting 
    Modern cloud applications frequently use React for frontend development. Kloudbean's cloud hosting services ensure your React applications run smoothly with optimized performance.
    
    
      Frequently Asked Questions 
      Q. Is this tool free to use? 
      
      Q. Does this tool store my code? 
      
      Q. Can I use this tool offline? 
      
      Q. Does this tool handle complex JSX structures? 
      
      Q. Will this tool convert React-specific features? 
      
     
    
    Ready to deploy your React project with efficient hosting? Host with Kloudbean Today! 
  
 
  
`;
}
// Format JSX with proper indentation
function formatJSX() {
  const inputJSX = document.getElementById('jsx-code').value.trim();
  if (!inputJSX) {
    showStatus('Please enter some JSX code to format.', 'invalid');
    return;
  }
  
  try {
    // Format the JSX
    const formatted = prettyFormatJSX(inputJSX);
    
    document.getElementById('jsx-code').value = formatted;
    updateLineNumbers();
    showStatus('JSX formatted successfully!', 'valid');
  } catch (error) {
    console.error('Formatting error:', error);
    showStatus('Error during JSX formatting: ' + error.message, 'invalid');
  }
}
// Pretty format JSX
function prettyFormatJSX(jsx) {
  // Simple formatter for JSX code
  const indent = '  '; // 2 spaces
  let result = '';
  let level = 0;
  let inTag = false;
  let inJS = false;
  let inComment = false;
  let inString = false;
  let stringChar = '';
  
  // Process each character
  for (let i = 0; i < jsx.length; i++) {
    const char = jsx[i];
    const nextChar = jsx[i + 1] || '';
    
    // Handle strings
    if ((char === '"' || char === "'" || char === "`") && !inComment) {
      if (inString && char === stringChar && jsx[i - 1] !== '\\') {
        inString = false;
      } else if (!inString) {
        inString = true;
        stringChar = char;
      }
      result += char;
      continue;
    }
    
    // Skip processing inside strings
    if (inString) {
      result += char;
      continue;
    }
    
    // Handle comments
    if (char === '/' && nextChar === '*' && !inComment) {
      inComment = true;
      result += char;
      continue;
    }
    if (char === '*' && nextChar === '/' && inComment) {
      inComment = false;
      result += char + nextChar;
      i++; // Skip next char
      continue;
    }
    if (inComment) {
      result += char;
      continue;
    }
    
    // Handle JSX tags
    if (char === '<' && !inTag && !inJS) {
      if (nextChar === '/') {
        // Closing tag
        level--;
      }
      inTag = true;
      result += '\n' + indent.repeat(level) + char;
      if (nextChar !== '/') {
        level++;
      }
      continue;
    }
    
    // Handle end of tags
    if (char === '>' && inTag) {
      inTag = false;
      result += char;
      // If self-closing tag
      if (jsx[i - 1] === '/') {
        level--;
      }
      continue;
    }
    
    // Handle curly braces (JS expressions)
    if (char === '{' && !inTag && !inJS) {
      inJS = true;
      result += char;
      continue;
    }
    if (char === '}' && inJS) {
      inJS = false;
      result += char;
      continue;
    }
    
    // Handle newlines
    if (char === '\n' && !inTag && !inJS) {
      result += '\n' + indent.repeat(level);
      continue;
    }
    
    // All other characters
    result += char;
  }
  
  // Clean up extra newlines
  return result
    .replace(/\n\s*\n/g, '\n')  // Remove empty lines
    .trim();                    // Trim the result
}
// Show status message
function showStatus(message, status) {
  const statusDiv = document.getElementById('status-message');
  statusDiv.textContent = message;
  statusDiv.className = `tool-status tool-${status}`;
  statusDiv.style.display = 'block';
  // Auto-hide status after 7 seconds
  setTimeout(() => {
    statusDiv.style.display = 'none';
  }, 7000);
}
// Clear all content
function clearAll() {
  document.getElementById('jsx-code').value = '';
  document.getElementById('html-output').value = '';
  document.getElementById('status-message').style.display = 'none';
  updateLineNumbers();
  updateOutputLineNumbers();
}
// When the page loads, attach event handlers
document.addEventListener('DOMContentLoaded', function() {
  // Initialize line numbers
  updateLineNumbers();
  updateOutputLineNumbers();
  
  // Modify input and output textareas to auto-resize and avoid scrolling
  const inputArea = document.getElementById('jsx-code');
  const outputArea = document.getElementById('html-output');
  inputArea.style.overflowY = 'hidden'; // Hide vertical scrollbar
  outputArea.style.overflowY = 'hidden'; // Hide vertical scrollbar
  
  // Initial height adjustment
  inputArea.style.height = 'auto';
  inputArea.style.height = (inputArea.scrollHeight) + 'px';
  outputArea.style.height = 'auto';
  outputArea.style.height = (outputArea.scrollHeight) + 'px';
  
  // Add event listener for input changes
  document.getElementById('jsx-code').addEventListener('input', updateLineNumbers);
  document.getElementById('jsx-code').addEventListener('keyup', updateLineNumbers);
  document.getElementById('jsx-code').addEventListener('scroll', function() {
    // Sync scroll position
    document.getElementById('line-numbers').scrollTop = this.scrollTop;
  });
  
  // Add event listener for output changes
  document.getElementById('html-output').addEventListener('input', function() {
    updateOutputLineNumbers();
    // Auto-adjust height to content
    this.style.height = 'auto';
    this.style.height = (this.scrollHeight) + 'px';
  });
  document.getElementById('html-output').addEventListener('keyup', updateOutputLineNumbers);
  document.getElementById('html-output').addEventListener('scroll', function() {
    // Sync scroll position
    document.getElementById('output-line-numbers').scrollTop = this.scrollTop;
  });
  
  // Clear input button
  document.getElementById('clear-input').addEventListener('click', function() {
    document.getElementById('jsx-code').value = '';
    document.getElementById('status-message').style.display = 'none';
    updateLineNumbers();
  });
  
  // Copy output button
  document.getElementById('copy-output').addEventListener('click', function() {
    const outputField = document.getElementById('html-output');
    outputField.select();
    document.execCommand('copy');
    // Show temporary success message
    const original = this.textContent;
    this.textContent = 'Copied!';
    setTimeout(() => {
      this.textContent = original;
    }, 1500);
  });
  
  // Add sample JSX button functionality - double click on empty input
  document.getElementById('jsx-code').addEventListener('dblclick', function() {
    if (this.value === '') {
      this.value = `function ProductCard({ product, onAddToCart }) {
  const { name, price, description, inStock, images } = product;
  
  return (
    
  );
}`;
      updateLineNumbers();
    }
  });
});