# =' FX JSX Plugin - Complete Cheat Sheet ## <� **Plugin Overview** **FX JSX** provides native JSX parsing, rendering, and reactive binding without transpilation. Parse JSX strings at runtime and render them to DOM with automatic FX node reactivity. ### **Core Features** -  **Native JSX Parsing** - No Babel/webpack needed -  **Reactive Expressions** - `{$$app.data}` auto-updates -  **Custom Components** - Register reusable component classes -  **Event Handling** - Full JavaScript expressions in attributes -  **Template Literals** - `jsx`` tagged templates -  **Fragment Support** - Multiple root elements --- ## =� **Installation & Setup** ### **Loading the Plugin** ```html ``` ### **Basic Usage** ```javascript // Simple JSX rendering jsx.render('
Hello World!
', '#container'); // With FX reactive expressions jsx.render('

{$$app.title}

', document.body); // Template literal syntax const element = jsx``; ``` --- ## =� **Core API Reference** ### **JSX Engine Methods** | Method | Description | Example | |--------|-------------|---------| | `jsx.render(jsxString, container, context)` | Parse and render JSX | `jsx.render('
Hello
', '#app')` | | `jsx.component(name, ComponentClass)` | Register custom component | `jsx.component('MyButton', ButtonComponent)` | | `jsx`` ` | Template literal JSX | `jsx\`{data}\`` | ### **Component Base Class** ```typescript class MyComponent extends FXJSXComponent { constructor(props, children) { super(props, children); this.state = { count: 0 }; } setState(updates) { // Updates both internal state and FX node super.setState(updates); } render() { // Return JSX element structure return { type: 'element', tagName: 'div', attributes: [ { name: 'className', value: 'my-component' } ], children: [ { type: 'text', content: `Count: ${this.state.count}` } ] }; } } ``` --- ## <� **JSX Syntax Guide** ### **Basic Elements** ```jsx // Simple elements jsx.render('
Hello World
', '#container'); // With attributes jsx.render('
Content
', '#app'); // Self-closing tags jsx.render('Description', '#gallery'); ``` ### **Reactive Expressions** ```jsx // FX node values (reactive) jsx.render('

{$$app.title}

', '#header'); // Complex expressions jsx.render(`

User: {$$user.name || 'Anonymous'}

Items: {$$data.items.length}
`, '#content'); // Calculations jsx.render('
Total: {$$cart.items.reduce((sum, item) => sum + item.price, 0)}
'); ``` ### **Event Handlers** ```jsx // Simple event handlers jsx.render(` `); // With event object jsx.render(` $$('form.name').set(e.target.value)} placeholder="Enter name" /> `); // Multiple events jsx.render(`
$$('hover').set(true)} onmouseleave={() => $$('hover').set(false)} > Hover me
`); ``` --- ## >� **Custom Components** ### **Creating Components** ```typescript // Simple component class Greeting extends FXJSXComponent { render() { return { type: 'element', tagName: 'h1', attributes: [], children: [ { type: 'text', content: `Hello ${this.props.name}!` } ] }; } } // Register component jsx.component('Greeting', Greeting); // Use component jsx.render('', '#app'); ``` ### **Stateful Components** ```typescript class Counter extends FXJSXComponent { constructor(props, children) { super(props, children); this.state = { count: props.initialCount || 0 }; } increment() { this.setState({ count: this.state.count + 1 }); } render() { return { type: 'element', tagName: 'div', attributes: [{ name: 'className', value: 'counter' }], children: [ { type: 'element', tagName: 'p', attributes: [], children: [ { type: 'text', content: `Count: ${this.state.count}` } ] }, { type: 'element', tagName: 'button', attributes: [ { name: 'onclick', value: { type: 'expression', value: '() => this.increment()' } } ], children: [ { type: 'text', content: 'Increment' } ] } ] }; } } ``` ### **Components with Props** ```typescript class UserCard extends FXJSXComponent { render() { const { name, email, avatar, isOnline } = this.props; return { type: 'element', tagName: 'div', attributes: [ { name: 'className', value: `user-card ${isOnline ? 'online' : 'offline'}` } ], children: [ { type: 'element', tagName: 'img', attributes: [ { name: 'src', value: avatar }, { name: 'alt', value: name } ], children: [] }, { type: 'element', tagName: 'div', attributes: [{ name: 'className', value: 'user-info' }], children: [ { type: 'element', tagName: 'h3', attributes: [], children: [{ type: 'text', content: name }] }, { type: 'element', tagName: 'p', attributes: [], children: [{ type: 'text', content: email }] } ] } ] }; } } // Usage jsx.render(` `, '#user-profile'); ``` --- ## � **Reactive Patterns** ### **FX Node Binding** ```jsx // Reactive text content jsx.render('

{$$app.title}

', '#header'); // Reactive attributes jsx.render('
Themed content
', '#content'); // Reactive styles jsx.render('
Colored text
'); // Complex reactive expressions jsx.render(`
{$$user.name} ({$$user.role}) {$$user.lastLogin ? 'Recently active' : 'Inactive'}
`); ``` ### **Two-Way Data Binding** ```jsx // Input to FX node jsx.render(` $$('form.username').set(e.target.value)} placeholder="Username" /> `, '#username-input'); // Checkbox binding jsx.render(` `); // Select dropdown jsx.render(` `); ``` ### **List Rendering** ```jsx // Simple list jsx.render(` `); // Interactive list jsx.render(`
{$$todos.map((todo, index) => \`
\${todo.text}
\`).join('')}
`); ``` --- ## <� **Template Literal API** ### **Basic Template Literals** ```javascript // Simple elements const heading = jsx`

Welcome to FX JSX

`; // With variables const name = 'John'; const greeting = jsx`

Hello, ${name}!

`; // With FX nodes const reactive = jsx`Current time: {$$app.currentTime}`; ``` ### **Complex Templates** ```javascript // Multi-line JSX const form = jsx`
handleSubmit(e)}>
`; // With expressions const card = jsx`

{$$user.name}

Member since: {new Date($$user.joinDate).getFullYear()}

`; ``` --- ## <� **Advanced Use Cases** ### **Conditional Rendering** ```jsx // Simple conditionals jsx.render(`
{$$user.isLoggedIn ? '
Welcome back!
' : '
Please log in
' }
`); // Complex conditionals jsx.render(`
{$$user.isAdmin ? \`

Admin Panel

\` : $$user.isPremium ? \`

Premium Features

\` : \`

Basic Features

\`}
`); ``` ### **Dynamic Component Loading** ```typescript // Dynamic component registry const components = { 'Button': ButtonComponent, 'Card': CardComponent, 'Modal': ModalComponent }; // Register components dynamically Object.entries(components).forEach(([name, component]) => { jsx.component(name, component); }); // Use dynamic components jsx.render(`
{$$ui.components.map(comp => \`<\${comp.type} ...props="\${JSON.stringify(comp.props)}" />\` ).join('')}
`); ``` ### **Error Boundaries** ```typescript class ErrorBoundary extends FXJSXComponent { constructor(props, children) { super(props, children); this.state = { hasError: false, error: null }; } render() { if (this.state.hasError) { return { type: 'element', tagName: 'div', attributes: [{ name: 'className', value: 'error-boundary' }], children: [ { type: 'element', tagName: 'h2', attributes: [], children: [{ type: 'text', content: 'Something went wrong' }] }, { type: 'element', tagName: 'p', attributes: [], children: [{ type: 'text', content: this.state.error?.message || 'Unknown error' }] } ] }; } return this.children[0] || { type: 'text', content: '' }; } } ``` --- ## = **Debugging & Development** ### **Debug Mode** ```javascript // Enable JSX debugging jsx.debug = true; // View parsed JSX structure const parsed = jsx.parse('
{$$app.data}
'); console.log('Parsed JSX:', parsed); // Monitor reactive updates $$('app.data').watch((newValue) => { console.log('JSX will re-render with:', newValue); }); ``` ### **Performance Optimization** ```javascript // Minimize re-renders by grouping FX updates function updateMultipleNodes() { // Batch updates to prevent multiple re-renders const updates = { 'user.name': 'New Name', 'user.email': 'new@email.com', 'user.status': 'updated' }; Object.entries(updates).forEach(([path, value]) => { $$(path).set(value); }); } // Use keys for list items to optimize rendering jsx.render(` `); ``` --- ## =� **Common Patterns & Best Practices** ###  **DO: Best Practices** ```jsx //  Use meaningful component names jsx.component('UserProfileCard', UserProfileComponent); //  Keep components small and focused class Button extends FXJSXComponent { render() { return { type: 'element', tagName: 'button', attributes: [ { name: 'className', value: `btn ${this.props.variant || 'primary'}` }, { name: 'onclick', value: this.props.onClick } ], children: [ { type: 'text', content: this.props.children || 'Button' } ] }; } } //  Use FX nodes for shared state jsx.render('
{$$app.globalMessage}
'); //  Batch related updates function updateUserProfile(userData) { Object.entries(userData).forEach(([key, value]) => { $$(`user.profile.${key}`).set(value); }); } ``` ### L **DON'T: Anti-patterns** ```jsx // L Don't inline complex logic in JSX jsx.render(`
{(() => { // Complex logic here - move to function let result = ''; for (let i = 0; i < items.length; i++) { result += `${items[i]}`; } return result; })()}
`); // L Don't forget to escape HTML in dynamic content jsx.render(`
{userInput}
`); // Potential XSS //  DO: Escape or use textContent jsx.render(`
{escapeHtml(userInput)}
`); // L Don't directly manipulate DOM in components class BadComponent extends FXJSXComponent { render() { // DON'T: Direct DOM manipulation setTimeout(() => { document.getElementById('my-element').style.color = 'red'; }, 1000); return { type: 'text', content: 'Bad Component' }; } } //  DO: Use FX nodes and reactive expressions class GoodComponent extends FXJSXComponent { componentDidMount() { setTimeout(() => { $$('component.color').set('red'); }, 1000); } render() { return { type: 'element', tagName: 'div', attributes: [ { name: 'style', value: { type: 'expression', value: '`color: ${$$("component.color")}`' } } ], children: [{ type: 'text', content: 'Good Component' }] }; } } ``` --- ## <� **Complete Real-World Example** ```typescript // Todo App with FX JSX class TodoApp extends FXJSXComponent { constructor(props, children) { super(props, children); // Initialize FX state $$('todos.list').set([]); $$('todos.newText').set(''); $$('todos.filter').set('all'); // all, active, completed } addTodo() { const text = $$('todos.newText').get(); if (!text.trim()) return; const todos = $$('todos.list').get(); todos.push({ id: Date.now(), text: text.trim(), completed: false, createdAt: new Date() }); $$('todos.list').set([...todos]); $$('todos.newText').set(''); } toggleTodo(id) { const todos = $$('todos.list').get(); const index = todos.findIndex(todo => todo.id === id); if (index >= 0) { todos[index].completed = !todos[index].completed; $$('todos.list').set([...todos]); } } deleteTodo(id) { const todos = $$('todos.list').get().filter(todo => todo.id !== id); $$('todos.list').set(todos); } render() { return { type: 'element', tagName: 'div', attributes: [{ name: 'className', value: 'todo-app' }], children: [ { type: 'element', tagName: 'header', attributes: [], children: [ { type: 'element', tagName: 'h1', attributes: [], children: [{ type: 'text', content: 'FX JSX Todo App' }] } ] }, { type: 'element', tagName: 'div', attributes: [{ name: 'className', value: 'add-todo' }], children: [ { type: 'element', tagName: 'input', attributes: [ { name: 'type', value: 'text' }, { name: 'placeholder', value: 'Add a new todo...' }, { name: 'value', value: { type: 'expression', value: '$$("todos.newText")' } }, { name: 'onchange', value: { type: 'expression', value: '(e) => $$("todos.newText").set(e.target.value)' } }, { name: 'onkeypress', value: { type: 'expression', value: '(e) => e.key === "Enter" && this.addTodo()' } } ], children: [] }, { type: 'element', tagName: 'button', attributes: [ { name: 'className', value: 'btn-primary' }, { name: 'onclick', value: { type: 'expression', value: '() => this.addTodo()' } } ], children: [{ type: 'text', content: 'Add Todo' }] } ] }, { type: 'element', tagName: 'div', attributes: [{ name: 'className', value: 'todo-list' }], children: [ { type: 'expression', content: `$$('todos.list').map(todo => \`
this.toggleTodo(\${todo.id})} /> \${todo.text}
\`).join('')` } ] } ] }; } } // Register and render the app jsx.component('TodoApp', TodoApp); jsx.render('', '#app'); ``` This comprehensive cheat sheet covers all aspects of the FX JSX plugin, from basic usage to advanced patterns and complete real-world examples. The plugin provides a powerful way to use JSX without transpilation while maintaining full reactivity with FX nodes.