Skip to content

x:text Directive

The x:text directive is used to dynamically update the text content of HTML elements.

Basic Usage

Syntax

html
<element x:text="propertyName">Fallback content</element>
<element x:text="computedValue">Loading...</element>
<element x:text="xctx.width">0</element>
<element x:text="count > 0 ? 'Yes' : 'No'">-</element>

Value Conversion

All values are automatically converted to string:

typescript
@xproperty() message: string = 'Hello';        // → "Hello"
@xproperty() count: number = 42;               // → "42"
@xproperty() isActive: boolean = true;         // → "true"
@xproperty() data: object = {x: 1};            // → '{"x":1}'
@xproperty() empty: null = null;               // → ""

Examples

Simple Binding

typescript
@Widget({
  selector: '.greeting-widget',
  template: `
    <div>
      <h2 x:text="title">Title</h2>
      <input type="text" x:model="userName">
      <p>Hello, <span x:text="userName">Guest</span>!</p>
    </div>
  `
})
export class GreetingWidget {
  @xproperty() title: string = 'Welcome';
  @xproperty() userName: string = '';
}

Computed Property

typescript
@Widget({
  selector: '.user-card',
  template: `
    <div>
      <h3 x:text="fullName">-</h3>
      <p x:text="ageCategory">-</p>
    </div>
  `
})
export class UserCard {
  @xproperty() firstName: string = 'John';
  @xproperty() lastName: string = 'Doe';
  @xproperty() age: number = 25;
  
  @xcomputed({ dependencies: ['firstName', 'lastName'] })
  get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
  
  @xcomputed({ dependencies: ['age'] })
  get ageCategory(): string {
    return this.age < 18 ? 'Young' : 'Adult';
  }
}

Context Usage

typescript
@Widget({
  selector: '.context-widget',
  template: `
    <div>
      <p>Width: <span x:text="xctx.width || 0">0</span>px</p>
      <p>Mobile: <span x:text="xctx.isMobile ? 'Yes' : 'No'">-</span></p>
    </div>
  `
})
export class ContextWidget {}

Conditional Expressions

typescript
@Widget({
  selector: '.status-widget',
  template: `
    <p x:text="score >= 50 ? 'Pass' : 'Fail'">-</p>
    <p x:text="items.length > 0 ? items.length + ' items' : 'Empty'">-</p>
    <p x:text="userName || 'Guest'">-</p>
  `
})
export class StatusWidget {
  @xproperty() score: number = 75;
  @xproperty() items: string[] = [];
  @xproperty() userName: string = '';
}

Usage with Loop

typescript
@Widget({
  selector: '.list-widget',
  template: `
    <template x:for="product in products">
      <div>
        <h4 x:text="product.name">-</h4>
        <p>Price: <span x:text="product.price">0</span> TL</p>
      </div>
    </template>
  `
})
export class ListWidget {
  @xproperty()
  products: Array<{name: string, price: number}> = [
    { name: 'Laptop', price: 15000 },
    { name: 'Mouse', price: 250 }
  ];
}

Formatting

typescript
@Widget({
  selector: '.format-widget',
  template: `
    <div>
      <p x:text="formattedPrice">₺0.00</p>
      <p x:text="formattedDate">-</p>
    </div>
  `
})
export class FormatWidget {
  @xproperty() price: number = 1234.56;
  @xproperty() date: Date = new Date();
  
  @xcomputed({ dependencies: ['price'] })
  get formattedPrice(): string {
    return `₺${this.price.toFixed(2)}`;
  }
  
  @xcomputed({ dependencies: ['date'] })
  get formattedDate(): string {
    return this.date.toLocaleDateString('en-US');
  }
}

Best Practices

✅ Correct

typescript
// With computed property
@xcomputed({ dependencies: ['items'] })
get itemCount(): number {
  return this.items.length;
}
// <p x:text="itemCount">0</p>

❌ Wrong

html
<!-- Complex calculation in template -->
<p x:text="items.filter(i => i.active).map(i => i.name).join(', ')">-</p>

Summary

  • Automatic conversion: All values are converted to string
  • Reactive: Automatically updates when property changes
  • Safe: Returns empty string for null/undefined
  • Conditional: Supports ternary operator
  • Computed: Compatible with computed values
  • Context: Accesses xctx values
  • Loop: Can be used inside x:for