Skip to content

x:if Directive

The x:if directive is used to show or hide HTML elements based on conditions.

Basic Usage

Syntax

html
<element x:if="condition">
  <!-- Visible if condition is true -->
</element>

Condition Types

Boolean Values

typescript
@Widget({
  selector: '.boolean-if',
  template: `
    <div x:if="isActive">Active</div>
    <div x:if="!isActive">Passive</div>
    <div x:if="isLoading">Loading...</div>
  `
})
export class BooleanIfWidget {
  @xproperty()
  isActive: boolean = true;
  
  @xproperty()
  isLoading: boolean = false;
}

Comparison Operators

typescript
@Widget({
  selector: '.comparison-if',
  template: `
    <div x:if="count > 0">Positive number</div>
    <div x:if="count === 0">Zero</div>
    <div x:if="count < 0">Negative number</div>
    <div x:if="status === 'active'">Status active</div>
    <div x:if="age >= 18">Adult</div>
  `
})
export class ComparisonIfWidget {
  @xproperty()
  count: number = 5;
  
  @xproperty()
  status: string = 'active';
  
  @xproperty()
  age: number = 25;
}

Nested Properties

typescript
@Widget({
  selector: '.nested-if',
  template: `
    <div x:if="user.isActive">User active</div>
    <div x:if="user.profile.isComplete">Profile completed</div>
    <div x:if="settings.notifications.enabled">Notifications on</div>
  `
})
export class NestedIfWidget {
  @xproperty()
  user = {
    isActive: true,
    profile: { isComplete: false }
  };
  
  @xproperty()
  settings = {
    notifications: { enabled: true }
  };
}

Computed Properties

typescript
@Widget({
  selector: '.computed-if',
  template: `
    <div x:if="canEdit">Edit button</div>
    <div x:if="isUrgent">Urgent action</div>
    <div x:if="hasPermission">Authorized content</div>
  `
})
export class ComputedIfWidget {
  @xproperty()
  user = { role: 'admin', permissions: ['edit'] };
  
  @xproperty()
  status: string = 'open';
  
  @xproperty()
  priority: string = 'high';
  
  @xcomputed({ dependencies: ['user.role', 'user.permissions'] })
  get canEdit(): boolean {
    return this.user.role === 'admin' || 
           this.user.permissions.includes('edit');
  }
  
  @xcomputed({ dependencies: ['status', 'priority'] })
  get isUrgent(): boolean {
    return this.status === 'open' && this.priority === 'high';
  }
  
  @xcomputed({ dependencies: ['user.role'] })
  get hasPermission(): boolean {
    return this.user.role === 'admin';
  }
}

If-Else Pattern

typescript
@Widget({
  selector: '.if-else',
  template: `
    <div>
      <div x:if="isLoggedIn">Welcome, user!</div>
      <div x:if="!isLoggedIn">Please log in</div>
    </div>
  `
})
export class IfElseWidget {
  @xproperty()
  isLoggedIn: boolean = false;
}

Usage with x:for

typescript
@Widget({
  selector: '.for-if',
  template: `
    <template x:for="item in items">
      <div>
        <span x:text="item.name"></span>
        <span x:if="item.isNew">NEW</span>
        <span x:if="item.discount > 0">Discounted</span>
        <button x:if="item.stock > 0">Add to Cart</button>
        <span x:if="item.stock === 0">Out of Stock</span>
      </div>
    </template>
  `
})
export class ForIfWidget {
  @xproperty()
  items = [
    { name: 'Product 1', isNew: true, discount: 20, stock: 10 },
    { name: 'Product 2', isNew: false, discount: 0, stock: 0 }
  ];
}

Dynamic Conditions

typescript
@Widget({
  selector: '.dynamic-if',
  template: `
    <div>
      <button x:on:click="toggleVisibility">Toggle</button>
      
      <div x:if="isVisible">
        <p>Visible content</p>
        <p>Counter: <span x:text="counter"></span></p>
      </div>
      
      <div x:if="counter > 5">Counter greater than 5</div>
    </div>
  `
})
export class DynamicIfWidget {
  @xproperty()
  isVisible: boolean = true;
  
  @xproperty()
  counter: number = 0;
  
  toggleVisibility(): void {
    this.isVisible = !this.isVisible;
    this.counter++;
  }
}

Form Validation

typescript
@Widget({
  selector: '.validation-if',
  template: `
    <form>
      <input x:model="email" type="email">
      <div x:if="email && !isValidEmail" class="error">
        Enter valid email
      </div>
      
      <input x:model="password" type="password">
      <div x:if="password && password.length < 6" class="error">
        Password must be at least 6 characters
      </div>
      
      <button x:if="isValidEmail && password.length >= 6">
        Submit
      </button>
    </form>
  `
})
export class ValidationIfWidget {
  @xproperty()
  email: string = '';
  
  @xproperty()
  password: string = '';
  
  @xcomputed({ dependencies: ['email'] })
  get isValidEmail(): boolean {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email);
  }
}

Loading States

typescript
@Widget({
  selector: '.loading-if',
  template: `
    <div>
      <button x:on:click="loadData" x:if="!isLoading">
        Load Data
      </button>
      
      <div x:if="isLoading">Loading...</div>
      
      <div x:if="!isLoading && data">
        <p x:text="data.message"></p>
      </div>
      
      <div x:if="!isLoading && error" class="error">
        <p x:text="error"></p>
      </div>
    </div>
  `
})
export class LoadingIfWidget {
  @xproperty()
  isLoading: boolean = false;
  
  @xproperty()
  data: any = null;
  
  @xproperty()
  error: string = '';
  
  async loadData(): Promise<void> {
    this.isLoading = true;
    this.error = '';
    
    try {
      // Simulated API call
      await new Promise(resolve => setTimeout(resolve, 1000));
      this.data = { message: 'Data loaded' };
    } catch (e) {
      this.error = 'Loading error';
    } finally {
      this.isLoading = false;
    }
  }
}

Multiple Conditions

typescript
@Widget({
  selector: '.multiple-if',
  template: `
    <div>
      <div x:if="isAdmin && isActive">Admin and Active</div>
      <div x:if="isPremium || hasDiscount">Premium or Discounted</div>
      <div x:if="score >= 80 && score <= 100">Successful</div>
      <div x:if="!isBlocked && emailVerified">Access Granted</div>
    </div>
  `
})
export class MultipleIfWidget {
  @xproperty()
  isAdmin: boolean = true;
  
  @xproperty()
  isActive: boolean = true;
  
  @xproperty()
  isPremium: boolean = false;
  
  @xproperty()
  hasDiscount: boolean = true;
  
  @xproperty()
  score: number = 85;
  
  @xproperty()
  isBlocked: boolean = false;
  
  @xproperty()
  emailVerified: boolean = true;
}

Summary

  • Conditional render: Show/hide based on boolean expressions
  • Comparison: ===, >, <, >=, <= operators
  • Nested properties: Access like user.profile.isComplete
  • Computed properties: Calculated conditions
  • Logical operators: &&, ||, !
  • x:for compatible: Conditional render inside loops
  • Dynamic: Automatic update when property changes